]> git.sesse.net Git - kdenlive/commitdiff
Fix some crashes on proxy operations
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 26 Jun 2011 20:59:38 +0000 (20:59 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 26 Jun 2011 20:59:38 +0000 (20:59 +0000)
svn path=/trunk/kdenlive/; revision=5732

14 files changed:
src/clipitem.cpp
src/clipproperties.cpp
src/clipproperties.h
src/customtrackview.cpp
src/docclipbase.cpp
src/docclipbase.h
src/kthumb.h
src/mainwindow.cpp
src/mainwindow.h
src/monitor.cpp
src/projectlist.cpp
src/projectlist.h
src/renderer.cpp
src/renderer.h

index 32d720e10bf10712fd92e9b3f223efd1b840ec9e..07878af299d7df5c41f776fbbee05167c310f351 100644 (file)
@@ -96,7 +96,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i
             m_endThumbTimer.setSingleShot(true);
             connect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
 
-            connect(this, SIGNAL(getThumb(int, int)), m_clip->thumbProducer(), SLOT(extractImage(int, int)));
+            connect(this, SIGNAL(getThumb(int, int)), m_clip, SLOT(slotExtractImage(int, int)));
 
             connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage)));
             connect(m_clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
@@ -110,7 +110,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i
     } else if (m_clipType == IMAGE || m_clipType == TEXT) {
         m_baseColor = QColor(141, 166, 215);
         if (m_clipType == TEXT) {
-            connect(this, SIGNAL(getThumb(int, int)), m_clip->thumbProducer(), SLOT(extractImage(int, int)));
+            connect(this, SIGNAL(getThumb(int, int)), m_clip, SLOT(slotExtractImage(int, int)));
             connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage)));
         }
         //m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio()), KdenliveSettings::trackheight());
@@ -1724,12 +1724,12 @@ void ClipItem::doGetIntraThumbs(QPainter *painter, const QPointF startPos, int o
     for (int i = start; i <= end; i++) {
 #if KDE_IS_VERSION(4,5,0)
         if (!view->m_pixmapCache->findPixmap(m_clip->fileURL().path() + "%" + QString::number(i), &p)) {
-            p = m_clip->thumbProducer()->extractImage(i, twidth, theight);
+            p = m_clip->extractImage(i, twidth, theight);
             view->m_pixmapCache->insertPixmap(m_clip->fileURL().path() + "%" + QString::number(i), p);
         }
 #else
         if (!view->m_pixmapCache->find(m_clip->fileURL().path() + "%" + QString::number(i), p)) {
-            p = m_clip->thumbProducer()->extractImage(i, twidth, theight);
+            p = m_clip->extractImage(i, twidth, theight);
             view->m_pixmapCache->insert(m_clip->fileURL().path() + "%" + QString::number(i), p);
         }
 #endif
index 875f85e94e4380a594016ce45bd9e378ec759287..5d1c9b40532b3d3076af7e316c51e99520a33cc8 100644 (file)
@@ -1022,10 +1022,8 @@ void ClipProperties::slotUpdateDurationFormat(int ix)
 void ClipProperties::slotDeleteProxy()
 {
       QString proxy = m_clip->getProperty("proxy");
-      QFile::remove(proxy);
-      QMap <QString, QString> props;
-      props.insert("proxy", QString());
-      emit applyNewClipProperties(m_clip->getId(), m_clip->properties(), props, false, true);
+      if (proxy.isEmpty()) return;
+      emit deleteProxy(proxy);
       if (m_proxyContainer) delete m_proxyContainer;
 }
 
index 27d3ffadd6371770ba0c166e4a1b3d9a4fcbb546..5dad49494b04b67eb975a57bfb427c0b062cdf23 100644 (file)
@@ -87,6 +87,7 @@ private:
 
 signals:
     void addMarker(const QString &, GenTime, QString);
+    void deleteProxy(const QString);
     void applyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool);
 };
 
index 844a171e64ffaa0b6934f91aff7236b851163218..6b2165ed3edb17fe60309f6756d99cdad9e129fc 100644 (file)
@@ -4130,6 +4130,7 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i
 void CustomTrackView::slotUpdateClip(const QString &clipId, bool reload)
 {
     QList<QGraphicsItem *> list = scene()->items();
+    QList <ClipItem *>clipList;
     ClipItem *clip = NULL;
     for (int i = 0; i < list.size(); ++i) {
         if (list.at(i)->type() == AVWIDGET) {
@@ -4139,10 +4140,12 @@ void CustomTrackView::slotUpdateClip(const QString &clipId, bool reload)
                 if (reload && !m_document->renderer()->mltUpdateClip(info, clip->xml(), clip->baseClip()->producer(info.track))) {
                     emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", info.startPos.frames(m_document->fps()), info.track), ErrorMessage);
                 }
-                clip->refreshClip(true, true);
+                else clipList.append(clip);
             }
         }
     }
+    for (int i = 0; i < clipList.count(); i++)
+        clipList.at(i)->refreshClip(true, true);
 }
 
 ClipItem *CustomTrackView::getClipItemAtEnd(GenTime pos, int track)
index 1246683e044d4ed3838e60aba814b104a989b957..cc719b0fc2dd59e572a1cc9d46e7fa50ca982944 100644 (file)
@@ -449,14 +449,15 @@ void DocClipBase::setValid()
 
 void DocClipBase::setProducer(Mlt::Producer *producer, bool reset, bool readPropertiesFromProducer)
 {
-    if (m_placeHolder && producer) {
+    if (producer == NULL || !producer->is_valid()) return;
+    if (reset) m_producerMutex.lock();
+    if (m_placeHolder) {
         char *tmp = qstrdup(i18n("Missing clip").toUtf8().constData());
         producer->set("markup", tmp);
         producer->set("bgcolour", "0xff0000ff");
         producer->set("pad", "10");
         delete[] tmp;
     }
-    if (producer == NULL /*|| (m_placeHolder && !reset)*/) return;
     if (m_thumbProd && (reset || !m_thumbProd->hasProducer())) m_thumbProd->setProducer(producer);
     if (reset) {
         // Clear all previous producers
@@ -479,12 +480,14 @@ void DocClipBase::setProducer(Mlt::Producer *producer, bool reset, bool readProp
                 m_audioTrackProducers[pos] = producer;
                 updated = true;
             }
+            if (reset) m_producerMutex.unlock();
             return;
         } else if (id.endsWith("video")) {
             if (m_videoOnlyProducer == NULL) {
                 m_videoOnlyProducer = producer;
                 updated = true;
             }
+            if (reset) m_producerMutex.unlock();
             return;
         }
         int pos = id.toInt();
@@ -509,6 +512,7 @@ void DocClipBase::setProducer(Mlt::Producer *producer, bool reset, bool readProp
     }
     if (updated && readPropertiesFromProducer && (m_clipType != COLOR && m_clipType != IMAGE && m_clipType != TEXT))
         setDuration(GenTime(producer->get_length(), KdenliveSettings::project_fps()));
+    if (reset) m_producerMutex.unlock();
 }
 
 static double getPixelAspect(QMap<QString, QString>& props) {
@@ -524,6 +528,7 @@ static double getPixelAspect(QMap<QString, QString>& props) {
 
 Mlt::Producer *DocClipBase::audioProducer(int track)
 {
+    m_producerMutex.lock();
     if (m_audioTrackProducers.count() <= track) {
         while (m_audioTrackProducers.count() - 1 < track) {
             m_audioTrackProducers.append(NULL);
@@ -535,13 +540,16 @@ Mlt::Producer *DocClipBase::audioProducer(int track)
             if (m_audioTrackProducers.at(i) != NULL) break;
         if (i < m_audioTrackProducers.count()) {
             // Could not find a valid producer for that clip, check in 
+            m_producerMutex.unlock();
             return m_audioTrackProducers.at(i);
         }
-            
+        m_producerMutex.unlock();
         Mlt::Producer *base = producer();
+        m_producerMutex.lock();
         m_audioTrackProducers[track] = cloneProducer(base);
         adjustProducerProperties(m_audioTrackProducers.at(track), QString(getId() + '_' + QString::number(track) + "_audio"), false, true);
     }
+    m_producerMutex.unlock();
     return m_audioTrackProducers.at(track);
 }
 
@@ -571,6 +579,7 @@ void DocClipBase::adjustProducerProperties(Mlt::Producer *prod, const QString &i
 
 Mlt::Producer *DocClipBase::videoProducer()
 {
+    m_producerMutex.lock();
     if (m_videoOnlyProducer == NULL) {
         int i;
         for (i = 0; i < m_baseTrackProducers.count(); i++)
@@ -579,17 +588,22 @@ Mlt::Producer *DocClipBase::videoProducer()
         m_videoOnlyProducer = cloneProducer(m_baseTrackProducers.at(i));
         adjustProducerProperties(m_videoOnlyProducer, QString(getId() + "_video"), true, false);
     }
+    m_producerMutex.unlock();
     return m_videoOnlyProducer;
 }
 
 Mlt::Producer *DocClipBase::producer(int track)
 {
+    m_producerMutex.lock();
     if (track == -1 || (m_clipType != AUDIO && m_clipType != AV && m_clipType != PLAYLIST)) {
         if (m_baseTrackProducers.count() == 0) return NULL;
         for (int i = 0; i < m_baseTrackProducers.count(); i++) {
-            if (m_baseTrackProducers.at(i) != NULL)
+            if (m_baseTrackProducers.at(i) != NULL) {
+                m_producerMutex.unlock();
                 return m_baseTrackProducers.at(i);
+            }
         }
+        m_producerMutex.unlock();
         return NULL;
     }
     if (track >= m_baseTrackProducers.count()) {
@@ -604,11 +618,13 @@ Mlt::Producer *DocClipBase::producer(int track)
 
         if (i >= m_baseTrackProducers.count()) {
             // Could not find a valid producer for that clip, check in 
+            m_producerMutex.unlock();
             return NULL;
         }
         m_baseTrackProducers[track] = cloneProducer(m_baseTrackProducers.at(i));
         adjustProducerProperties(m_baseTrackProducers.at(track), QString(getId() + '_' + QString::number(track)), false, false);
     }
+    m_producerMutex.unlock();
     return m_baseTrackProducers.at(track);
 }
 
@@ -616,16 +632,19 @@ Mlt::Producer *DocClipBase::producer(int track)
 Mlt::Producer *DocClipBase::cloneProducer(Mlt::Producer *source)
 {
     Mlt::Producer *result = NULL;
-    if (KIO::NetAccess::exists(KUrl(source->get("resource")), KIO::NetAccess::SourceSide, 0)) {
-        result = new Mlt::Producer(*source->profile(), source->get("resource"));
+    QString url = source->get("resource");
+    if (KIO::NetAccess::exists(KUrl(url), KIO::NetAccess::SourceSide, 0)) {
+        char *tmp = qstrdup(url.toUtf8().constData());
+        result = new Mlt::Producer(*source->profile(), tmp);
+        delete[] tmp;
     }
-    if (result == NULL) {
+    if (result == NULL || !result->is_valid()) {
         // placeholder clip
         QString txt = "+" + i18n("Missing clip") + ".txt";
         char *tmp = qstrdup(txt.toUtf8().constData());
         result = new Mlt::Producer(*source->profile(), tmp);
         delete[] tmp;
-        if (result == NULL)
+        if (result == NULL || !result->is_valid())
             result = new Mlt::Producer(*source->profile(), "colour:red");
         else {
             result->set("bgcolour", "0xff0000ff");
@@ -932,6 +951,7 @@ void DocClipBase::refreshThumbUrl()
 
 void DocClipBase::setProperty(const QString &key, const QString &value)
 {
+    QString oldProxy = m_properties.value("proxy");
     m_properties.insert(key, value);
     if (key == "resource") {
         getFileHash(value);
@@ -1001,7 +1021,7 @@ void DocClipBase::setProperty(const QString &key, const QString &value)
         // If value is "-", that means user manually disabled proxy on this clip
         if (value.isEmpty() || value == "-") {
             // reset proxy
-            emit abortProxy(m_id);
+            emit abortProxy(m_id, oldProxy);
         }
         else {
             emit createProxy(m_id);
@@ -1122,4 +1142,28 @@ bool DocClipBase::hasAudioCodec(const QString &codec) const
 }
 
 
+void DocClipBase::slotExtractImage(int frame, int frame2)
+{
+    if (m_thumbProd == NULL) return;
+    m_thumbProd->extractImage(frame, frame2);
+}
+
+void DocClipBase::slotBlock()
+{
+    m_producerMutex.lock();
+}
+
+void DocClipBase::slotRelease()
+{
+    m_producerMutex.unlock();
+}
+
+QPixmap DocClipBase::extractImage(int frame, int width, int height)
+{
+    if (m_thumbProd == NULL) return QPixmap(width, height);
+    m_producerMutex.lock();
+    QPixmap p = m_thumbProd->extractImage(frame, width, height);
+    m_producerMutex.unlock();
+    return p;
+}
 
index b559ded7c14ba5688460b55945f233c0b2dc3a99..c66fcfde9174523db354c312cb729c467d7137ae 100644 (file)
@@ -203,6 +203,7 @@ Q_OBJECT public:
     bool hasAudioCodec(const QString &codec) const;
     bool checkHash() const;
     void setPlaceHolder(bool place);
+    QPixmap extractImage(int frame, int width, int height);
 
 private:   // Private attributes
 
@@ -238,6 +239,9 @@ private:   // Private attributes
     QMap <QString, QString> m_properties;
     /** Holds clip metadata like author, copyright,... */
     QMap <QString, QString> m_metadata;
+    
+    /** Try to make sure we don't delete a producer while using it */
+    QMutex m_producerMutex;
 
     /** Create connections for audio thumbnails */
     void slotCreateAudioTimer();
@@ -250,6 +254,7 @@ private:   // Private attributes
     /** @brief Create another instance of a producer. */
     Mlt::Producer *cloneProducer(Mlt::Producer *source);
 
+   
 public slots:
     void updateAudioThumbnail(QMap<int, QMap<int, QByteArray> > data);
     bool slotGetAudioThumbs();
@@ -268,14 +273,18 @@ public slots:
     void setMetadata(QMap <QString, QString> properties);
     QMap <QString, QString> properties() const;
     QMap <QString, QString> metadata() const;
-
+    void slotExtractImage(int frame, int frame2);
+    /** @brief Lock mutex to prevent changing producers while operation. */
+    void slotBlock();
+    /** @brief Release mutex preventing a change in producers. */
+    void slotRelease();
 
 signals:
     void gotAudioData();
     /** @brief Generate a proxy clip (lower resolution copy) named like the clip's hash. */
     void createProxy(const QString id);
     /** @brief Abort creation of the proxy clip (lower resolution copy). */
-    void abortProxy(const QString id);
+    void abortProxy(const QString id, const QString proxyPath);
 };
 
 #endif
index 598cda56e92e0752da4450894d68404123fee1e2..489001752d75fe1b2ae7601af691974497dee4ab 100644 (file)
@@ -60,10 +60,10 @@ Q_OBJECT public:
     bool hasProducer() const;
     void clearProducer();
     void updateThumbUrl(const QString &hash);
-
-public slots:
     void extractImage(int frame, int frame2);
     QPixmap extractImage(int frame, int width, int height);
+
+public slots:
     void updateClipUrl(KUrl url, const QString &hash);
     static QPixmap getImage(KUrl url, int width, int height);
 //    static QPixmap getImage(QDomElement xml, int frame, int width, int height);
index 380128f695754d207a6b8ca36a029d836a3fd835..2ff3cfdf79cf939ccd2b647c53556de889e0373b 100644 (file)
@@ -201,7 +201,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     m_clipMonitorDock->setObjectName("clip_monitor");
     m_clipMonitor = new Monitor("clip", m_monitorManager, QString(), m_timelineArea);
     m_clipMonitorDock->setWidget(m_clipMonitor);
-
+    connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint)));
+    
     m_projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this);
     m_projectMonitorDock->setObjectName("project_monitor");
     m_projectMonitor = new Monitor("project", m_monitorManager, QString());
@@ -851,6 +852,8 @@ void MainWindow::slotConnectMonitors()
     connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool, bool)));
 
     connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &, bool)));
+    
+    connect(m_projectMonitor->render, SIGNAL(blockClipMonitor(const QString)), this, SLOT(slotBlockClipMonitor(const QString)));
     connect(m_projectMonitor->render, SIGNAL(removeInvalidProxy(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidProxy(const QString &, bool)));
 
     connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(const QString &, bool)), m_projectList, SLOT(slotRefreshClipThumbnail(const QString &, bool)));
@@ -2424,7 +2427,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             m_effectStack->clear();
         }
         //m_activeDocument->setRenderer(NULL);
-        disconnect(m_projectList, SIGNAL(clipSelected(DocClipBase *)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *)));
         disconnect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), m_monitorManager, SLOT(slotRefreshCurrentMonitor()));
         m_clipMonitor->stop();
     }
@@ -2434,7 +2436,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     m_projectList->setDocument(doc);
     m_transitionConfig->updateProjectFormat(doc->mltProfile(), doc->timecode(), doc->tracksList());
     m_effectStack->updateProjectFormat(doc->mltProfile(), doc->timecode());
-    connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint)));
     connect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), m_monitorManager, SLOT(slotRefreshCurrentMonitor()));
     connect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), trackView->projectView(), SLOT(slotRefreshThumbs(const QString &, bool)));
     connect(m_projectList, SIGNAL(clipNeedsReload(const QString&, bool)), trackView->projectView(), SLOT(slotUpdateClip(const QString &, bool)));
@@ -3171,6 +3172,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
     // any type of clip but a title
     ClipProperties *dia = new ClipProperties(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this);
     connect(dia, SIGNAL(addMarker(const QString &, GenTime, QString)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, GenTime, QString)));
+    connect(dia, SIGNAL(deleteProxy(const QString)), m_projectList, SLOT(slotDeleteProxy(const QString)));
     connect(dia, SIGNAL(applyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool)), this, SLOT(slotApplyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool)));
     dia->show();
 }
@@ -4336,7 +4338,10 @@ void MainWindow::slotOpenBackupDialog(const KUrl url)
     delete dia;
 }
 
-
+void MainWindow::slotBlockClipMonitor(const QString id)
+{
+    if (m_clipMonitor->activeClip() && m_clipMonitor->activeClip()->getId() == id) m_clipMonitor->slotSetXml(NULL);
+}
 
 
 
index 9ae254db655924d1473693242b2a46b162a19d6c..f948e4cc9c5f72ff2c186249a26a1bfdcc1a0f0c 100644 (file)
@@ -543,6 +543,8 @@ private slots:
     void slotInsertNotesTimecode();
     /** @brief Open the project's backupdialog. */
     void slotOpenBackupDialog(const KUrl url = KUrl());
+    /** @brief Make sure to block clip monitor before deleting a clip's producer. */
+    void slotBlockClipMonitor(const QString id);
 
 signals:
     Q_SCRIPTABLE void abortRenderJob(const QString &url);
index ab0cc3cfe1ef8f6f70641d769bc0a1ad20ad0c6c..54c708bdff3f45f00dea25f0a7c884410badf69c 100644 (file)
@@ -736,7 +736,7 @@ void Monitor::stop()
 
 void Monitor::start()
 {
-    if (render) render->start();
+    if (render && (m_name != "clip" || m_currentClip != NULL)) render->start();
     connect(render, SIGNAL(rendererPosition(int)), this, SLOT(seekCursor(int)));
 }
 
@@ -826,7 +826,9 @@ void Monitor::slotSetXml(DocClipBase *clip, QPoint zone, const int position)
             // MLT CONSUMER is broken
             kDebug(QtWarningMsg) << "ERROR, Cannot start monitor";
         }
-    } else if (position != -1) render->seek(position);
+    } else {
+        if (position != -1) render->seek(position);
+    }
     if (!zone.isNull()) {
         m_ruler->setZone(zone.x(), zone.y());
         render->seek(zone.x());
index 102896c341dc18f28f965b6ba7741ee0367eb9f5..e723b9773c53910c672342088d19dad36885d26f 100644 (file)
@@ -1016,7 +1016,7 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
     }
     if (item->data(0, DurationRole).isNull()) item->setData(0, DurationRole, i18n("Loading"));
     connect(clip, SIGNAL(createProxy(const QString)), this, SLOT(slotCreateProxy(const QString)));
-    connect(clip, SIGNAL(abortProxy(const QString)), this, SLOT(slotAbortProxy(const QString)));
+    connect(clip, SIGNAL(abortProxy(const QString, const QString)), this, SLOT(slotAbortProxy(const QString, const QString)));
     if (getProperties) {
         m_listView->processLayout();
         QDomElement e = clip->toXML().cloneNode().toElement();
@@ -1072,28 +1072,42 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
         m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
-void ProjectList::slotGotProxy(const QString &id)
+void ProjectList::slotGotProxy(const QString &proxyPath)
 {
-    ProjectItem *item = getItemById(id);
-    if (item) {
-        // Proxy clip successfully created
-        QDomElement e = item->referencedClip()->toXML().cloneNode().toElement();  
-        //e.removeAttribute("file_hash");
+    if (proxyPath.isEmpty()) return;
+    QTreeWidgetItemIterator it(m_listView);
+    ProjectItem *item;
 
-        // Make sure we get the correct producer length if it was adjusted in timeline
-        CLIPTYPE t = item->clipType();
-        if (t == COLOR || t == IMAGE || t == SLIDESHOW || t == TEXT) {
-            int length = QString(item->referencedClip()->producerProperty("length")).toInt();
-            if (length > 0 && !e.hasAttribute("length")) {
-                e.setAttribute("length", length);
-            }
+    while (*it) {
+        if ((*it)->type() == PROJECTCLIPTYPE) {
+            item = static_cast <ProjectItem *>(*it);
+            if (item->referencedClip()->getProperty("proxy") == proxyPath)
+                slotGotProxy(item);
         }
-        e.setAttribute("replace", 1);
-        m_infoQueue.insert(id, e);
-        if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
+        ++it;
     }
 }
 
+void ProjectList::slotGotProxy(ProjectItem *item)
+{
+    if (item == NULL) return;
+    DocClipBase *clip = item->referencedClip();
+    // Proxy clip successfully created
+    QDomElement e = clip->toXML().cloneNode().toElement();  
+
+    // Make sure we get the correct producer length if it was adjusted in timeline
+    CLIPTYPE t = item->clipType();
+    if (t == COLOR || t == IMAGE || t == SLIDESHOW || t == TEXT) {
+        int length = QString(clip->producerProperty("length")).toInt();
+        if (length > 0 && !e.hasAttribute("length")) {
+            e.setAttribute("length", length);
+        }
+    }
+    e.setAttribute("replace", 1);
+    m_infoQueue.insert(clip->getId(), e);
+    if (!m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);   
+}
+
 void ProjectList::slotResetProjectList()
 {
     m_listView->clear();
@@ -1220,7 +1234,6 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged)
             }
             item->setData(0, UsageRole, QString::number(item->numReferences()));
         }
-        //qApp->processEvents();
         ++it;
     }
 
@@ -1492,7 +1505,6 @@ void ProjectList::setDocument(KdenliveDoc *doc)
     m_timecode = doc->timecode();
     m_commandStack = doc->commandStack();
     m_doc = doc;
-    m_proxyList.clear();
 
     QMap <QString, QString> flist = doc->clipManager()->documentFolderList();
     QStringList openedFolders = doc->getExpandedFolders();
@@ -1619,7 +1631,7 @@ void ProjectList::slotRefreshClipThumbnail(QTreeWidgetItem *it, bool update)
         else if (clip->clipType() == IMAGE)
             pix = QPixmap::fromImage(KThumb::getFrame(item->referencedClip()->producer(), 0, width, height));
         else
-            pix = item->referencedClip()->thumbProducer()->extractImage(frame, width, height);
+            pix = item->referencedClip()->extractImage(frame, width, height);
 
         if (!pix.isNull()) {
             monitorItemEditing(false);
@@ -1647,6 +1659,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
     }
     m_processingClips.removeAll(clipId);
     if (m_infoQueue.isEmpty() && m_processingClips.isEmpty()) m_listView->setEnabled(true);
+
     if (item && producer) {
         //m_listView->blockSignals(true);
         monitorItemEditing(false);
@@ -1657,7 +1670,6 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
             item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled);
             toReload = clipId;
         }
-
         // Proxy stuff
         QString size = properties.value("frame_size");
         if (!useProxy() && clip->getProperty("proxy").isEmpty()) setProxyStatus(item, NOPROXY);
@@ -1668,7 +1680,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
             CLIPTYPE t = item->clipType();
             if (t == IMAGE) maxSize = m_doc->getDocumentProperty("proxyimageminsize").toInt();
             else maxSize = m_doc->getDocumentProperty("proxyminsize").toInt();
-            if ((size.section('x', 0, 0).toInt() > maxSize || size.section('x', 1, 1).toInt() > maxSize) && (((t == AV || t == VIDEO || t == PLAYLIST) && generateProxy()) || (t == IMAGE && generateImageProxy()))) {
+            if ((((t == AV || t == VIDEO || t == PLAYLIST) && generateProxy()) || (t == IMAGE && generateImageProxy())) && (size.section('x', 0, 0).toInt() > maxSize || size.section('x', 1, 1).toInt() > maxSize)) {
                 if (clip->getProperty("proxy").isEmpty()) {
                     KUrl proxyPath = m_doc->projectFolder();
                     proxyPath.addPath("proxy/");
@@ -1684,49 +1696,40 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
                 }
             }
         }
-        
         clip->setProducer(producer, replace);
         clip->askForAudioThumbs();
+
         if (!replace && item->data(0, Qt::DecorationRole).isNull())
             requestClipThumbnail(clipId);
         if (!toReload.isEmpty())
             item->slotSetToolTip();
 
-        if (m_listView->isEnabled() && replace) {
-            // update clip in clip monitor
-            emit clipSelected(NULL);
-            emit clipSelected(clip);
-            //TODO: Make sure the line below has no side effect
-            toReload = clipId;
-        }
-        /*else {
-            // Check if duration changed.
-            emit receivedClipDuration(clipId);
-            delete producer;
-        }*/
         if (m_listView->isEnabled())
             monitorItemEditing(true);
-        /*if (item->icon(0).isNull()) {
-            requestClipThumbnail(clipId);
-        }*/
     } else kDebug() << "////////  COULD NOT FIND CLIP TO UPDATE PRPS...";
     if (selectClip && m_infoQueue.isEmpty()) {
-    if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) {
-        m_listView->setCurrentItem(item);
-        bool updatedProfile = false;
-        if (item->parent()) {
-            if (item->parent()->type() == PROJECTFOLDERTYPE)
-                static_cast <FolderProjectItem *>(item->parent())->switchIcon();
-        } else if (KdenliveSettings::checkfirstprojectclip() &&  m_listView->topLevelItemCount() == 1) {
-            // this is the first clip loaded in project, check if we want to adjust project settings to the clip
-            updatedProfile = adjustProjectProfileToItem(item);
-        }
-        if (updatedProfile == false) emit clipSelected(item->referencedClip());
-    } else {
-        int max = m_doc->clipManager()->clipsCount();
-        emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
-    }
+        if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) {
+            m_listView->setCurrentItem(item);
+            bool updatedProfile = false;
+            if (item->parent()) {
+                if (item->parent()->type() == PROJECTFOLDERTYPE)
+                    static_cast <FolderProjectItem *>(item->parent())->switchIcon();
+            } else if (KdenliveSettings::checkfirstprojectclip() &&  m_listView->topLevelItemCount() == 1) {
+                // this is the first clip loaded in project, check if we want to adjust project settings to the clip
+                updatedProfile = adjustProjectProfileToItem(item);
+            }
+            if (updatedProfile == false) emit clipSelected(item->referencedClip());
+        } else {
+            int max = m_doc->clipManager()->clipsCount();
+            emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
+        }
     }
+    if (item && m_listView->isEnabled() && replace) {
+            // update clip in clip monitor
+            emit clipSelected(item->referencedClip());
+            //TODO: Make sure the line below has no side effect
+            toReload = clipId;
+        }
     if (!toReload.isEmpty())
         emit clipNeedsReload(toReload, true);
 
@@ -2019,7 +2022,7 @@ void ProjectList::addClipCut(const QString &id, int in, int out, const QString d
             m_listView->scrollToItem(sub);
             m_listView->editItem(sub, 1);
         }
-        QPixmap p = clip->referencedClip()->thumbProducer()->extractImage(in, (int)(sub->sizeHint(0).height()  * m_render->dar()), sub->sizeHint(0).height() - 2);
+        QPixmap p = clip->referencedClip()->extractImage(in, (int)(sub->sizeHint(0).height()  * m_render->dar()), sub->sizeHint(0).height() - 2);
         sub->setData(0, Qt::DecorationRole, p);
         m_doc->cachePixmap(clip->getClipHash() + '#' + QString::number(in), p);
         monitorItemEditing(true);
@@ -2150,59 +2153,59 @@ void ProjectList::slotCreateProxy(const QString id)
 {
     ProjectItem *item = getItemById(id);
     if (!item || item->isProxyRunning() || item->referencedClip()->isPlaceHolder()) return;
-    setProxyStatus(id, PROXYWAITING);
-    if (m_abortProxyId.contains(id)) m_abortProxyId.removeAll(id);
-    QtConcurrent::run(this, &ProjectList::slotGenerateProxy, id);
+    QString path = item->referencedClip()->getProperty("proxy");
+    if (path.isEmpty()) {
+        setProxyStatus(path, PROXYCRASHED);
+        return;
+    }
+    setProxyStatus(path, PROXYWAITING);
+    if (m_abortProxy.contains(path)) m_abortProxy.removeAll(path);
+    if (m_processingProxy.contains(path)) {
+        // Proxy is already being generated
+        return;
+    }
+    if (QFile::exists(path)) {
+        // Proxy already created
+        setProxyStatus(path, PROXYDONE);
+        slotGotProxy(path);
+        return;
+    }
+    m_processingProxy.append(path);
+    QtConcurrent::run(this, &ProjectList::slotGenerateProxy, path, item->clipUrl().path(), item->clipType(), QString(item->referencedClip()->producerProperty("_exif_orientation")).toInt());
 }
 
-void ProjectList::slotAbortProxy(const QString id)
+void ProjectList::slotAbortProxy(const QString id, const QString path)
 {
-    if (m_proxyList.contains(id)) m_proxyList.removeAll(id);
+    QTreeWidgetItemIterator it(m_listView);
     ProjectItem *item = getItemById(id);
-    if (item) {
-      emit projectModified();
-      if (item->isProxyReady()) slotGotProxy(id);
-      else if (item->isProxyRunning()) m_abortProxyId << id;
-      setProxyStatus(id, NOPROXY);
+    setProxyStatus(item, NOPROXY);
+    slotGotProxy(item);
+    if (!path.isEmpty() && m_processingProxy.contains(path)) {
+        m_abortProxy << path;
+        setProxyStatus(path, NOPROXY);
     }
 }
 
-void ProjectList::slotGenerateProxy(const QString id)
+void ProjectList::slotGenerateProxy(const QString destPath, const QString sourcePath, int clipType, int exif_orientation)
 {
-    setProxyStatus(id, CREATINGPROXY);
-    ProjectItem *item = getItemById(id);
-    if (item == NULL) return;
-    QString path = item->referencedClip()->getProperty("proxy");
-    if (path.isEmpty()) {
-        setProxyStatus(id, PROXYCRASHED);
-        return;
-    }
-
-    if (QFile::exists(path)) {
-        setProxyStatus(id, PROXYDONE);
-        slotGotProxy(id);
+    emit projectModified();
+    // Make sure proxy path is writable
+    QFile file(destPath);
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+        setProxyStatus(destPath, PROXYCRASHED);
         return;
     }
-    else {
-        emit projectModified();
-        // Make sure proxy path is writable
-        QFile file(path);
-        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
-            setProxyStatus(id, PROXYCRASHED);
-            return;
-        }
-        file.close();
-        QFile::remove(path);
-    }
-
-    QString url = item->clipUrl().path();
+    file.close();
+    QFile::remove(destPath);
+    
+    setProxyStatus(destPath, CREATINGPROXY);
 
     // Special case: playlist clips (.mlt or .kdenlive project files)
-    if (item->clipType() == PLAYLIST) {
+    if (clipType == PLAYLIST) {
         // change FFmpeg params to MLT format
         QStringList parameters;
-        parameters << url;
-        parameters << "-consumer" << "avformat:" + path;
+        parameters << sourcePath;
+        parameters << "-consumer" << "avformat:" + destPath;
         QStringList params = m_doc->getDocumentProperty("proxyparams").simplified().split('-', QString::SkipEmptyParts);
         
         foreach(QString s, params) {
@@ -2216,8 +2219,8 @@ void ProjectList::slotGenerateProxy(const QString id)
         
         parameters.append(QString("real_time=-%1").arg(KdenliveSettings::mltthreads()));
 
-        // currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy
-        double display_ratio = KdenliveDoc::getDisplayRatio(url);
+        //TODO: currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy
+        double display_ratio = KdenliveDoc::getDisplayRatio(sourcePath);
         parameters << "aspect=" + QString::number(display_ratio);
 
         //kDebug()<<"TRANSCOD: "<<parameters;
@@ -2227,38 +2230,40 @@ void ProjectList::slotGenerateProxy(const QString id)
         int result = -1;
         while (myProcess.state() != QProcess::NotRunning) {
             // building proxy file
-            if (m_abortProxyId.contains(id)) {
+            if (m_abortProxy.contains(destPath)) {
                 myProcess.close();
                 myProcess.waitForFinished();
-                m_abortProxyId.removeAll(id);
-                QFile::remove(path);
-                setProxyStatus(id, NOPROXY);
+                m_abortProxy.removeAll(destPath);
+                m_processingProxy.removeAll(destPath);
+                QFile::remove(destPath);
+                setProxyStatus(destPath, NOPROXY);
                 result = -2;
 
             }
             myProcess.waitForFinished(500);
         }
         myProcess.waitForFinished();
+        m_processingProxy.removeAll(destPath);
         if (result == -1) result = myProcess.exitStatus();
         if (result == 0) {
             // proxy successfully created
-            setProxyStatus(id, PROXYDONE);
-            slotGotProxy(id);
+            setProxyStatus(destPath, PROXYDONE);
+            slotGotProxy(destPath);
         }
         else if (result == 1) {
             // Proxy process crashed
-            QFile::remove(path);
-            setProxyStatus(id, PROXYCRASHED);
+            QFile::remove(destPath);
+            setProxyStatus(destPath, PROXYCRASHED);
         }   
 
     }
     
-    if (item->clipType() == IMAGE) {
+    if (clipType == IMAGE) {
         // Image proxy
-        QImage i(url);
+        QImage i(sourcePath);
         if (i.isNull()) {
             // Cannot load image
-            setProxyStatus(id, PROXYCRASHED);
+            setProxyStatus(destPath, PROXYCRASHED);
             return;
         }
         QImage proxy;
@@ -2266,7 +2271,6 @@ void ProjectList::slotGenerateProxy(const QString id)
         //TODO: Make it be configurable?
         if (i.width() > i.height()) proxy = i.scaledToWidth(m_render->frameRenderWidth());
         else proxy = i.scaledToHeight(m_render->renderHeight());
-        int exif_orientation = QString(item->referencedClip()->producerProperty("_exif_orientation")).toInt();
         if (exif_orientation > 1) {
             // Rotate image according to exif data
             QImage processed;
@@ -2298,35 +2302,39 @@ void ProjectList::slotGenerateProxy(const QString id)
                   break;
               }
               processed = proxy.transformed( matrix );
-              processed.save(path);
+              processed.save(destPath);
         }
-        else proxy.save(path);
-        setProxyStatus(id, PROXYDONE);
-        slotGotProxy(id);
+        else proxy.save(destPath);
+        setProxyStatus(destPath, PROXYDONE);
+        slotGotProxy(destPath);
+        m_abortProxy.removeAll(destPath);
+        m_processingProxy.removeAll(destPath);
         return;
     }
 
     QStringList parameters;
-    parameters << "-i" << url;
+    parameters << "-i" << sourcePath;
     QString params = m_doc->getDocumentProperty("proxyparams").simplified();
     foreach(QString s, params.split(' '))
     parameters << s;
 
     // Make sure we don't block when proxy file already exists
     parameters << "-y";
-    parameters << path;
+    parameters << destPath;
+    kDebug()<<"// STARTING PROXY GEN: "<<parameters;
     QProcess myProcess;
     myProcess.start("ffmpeg", parameters);
     myProcess.waitForStarted();
     int result = -1;
     while (myProcess.state() != QProcess::NotRunning) {
         // building proxy file
-        if (m_abortProxyId.contains(id)) {
+        if (m_abortProxy.contains(destPath)) {
             myProcess.close();
             myProcess.waitForFinished();
-            m_abortProxyId.removeAll(id);
-            QFile::remove(path);
-            setProxyStatus(id, NOPROXY);
+            m_abortProxy.removeAll(destPath);
+            m_processingProxy.removeAll(destPath);
+            QFile::remove(destPath);
+            setProxyStatus(destPath, NOPROXY);
             result = -2;
             
         }
@@ -2336,14 +2344,16 @@ void ProjectList::slotGenerateProxy(const QString id)
     if (result == -1) result = myProcess.exitStatus();
     if (result == 0) {
         // proxy successfully created
-        setProxyStatus(id, PROXYDONE);
-        slotGotProxy(id);
+        setProxyStatus(destPath, PROXYDONE);
+        slotGotProxy(destPath);
     }
     else if (result == 1) {
         // Proxy process crashed
-        QFile::remove(path);
-        setProxyStatus(id, PROXYCRASHED);
+        QFile::remove(destPath);
+        setProxyStatus(destPath, PROXYCRASHED);
     }
+    m_abortProxy.removeAll(destPath);
+    m_processingProxy.removeAll(destPath);
 }
 
 void ProjectList::updateProxyConfig()
@@ -2466,10 +2476,47 @@ void ProjectList::slotProxyCurrentItem(bool doProxy)
     //if (!m_infoQueue.isEmpty() && !m_queueRunner.isRunning() && m_processingClips.isEmpty()) m_queueRunner = QtConcurrent::run(this, &ProjectList::slotProcessNextClipInQueue);
 }
 
-void ProjectList::setProxyStatus(const QString id, PROXYSTATUS status)
+
+void ProjectList::slotDeleteProxy(const QString proxyPath)
 {
-    ProjectItem *item = getItemById(id);
-    setProxyStatus(item, status);
+    if (proxyPath.isEmpty()) return;
+    QUndoCommand *proxyCommand = new QUndoCommand();
+    proxyCommand->setText(i18n("Remove Proxy"));
+    QTreeWidgetItemIterator it(m_listView);
+    ProjectItem *item;
+    while (*it) {
+        if ((*it)->type() == PROJECTCLIPTYPE) {
+            item = static_cast <ProjectItem *>(*it);
+            if (item->referencedClip()->getProperty("proxy") == proxyPath) {
+                QMap <QString, QString> props;
+                props.insert("proxy", QString());
+                new EditClipCommand(this, item->clipId(), item->referencedClip()->properties(), props, true, proxyCommand);
+            
+            }
+        }
+        ++it;
+    }
+    if (proxyCommand->childCount() == 0)
+        delete proxyCommand;
+    else
+        m_commandStack->push(proxyCommand);
+    QFile::remove(proxyPath);
+}
+
+void ProjectList::setProxyStatus(const QString proxyPath, PROXYSTATUS status)
+{
+    if (proxyPath.isEmpty()) return;
+    QTreeWidgetItemIterator it(m_listView);
+    ProjectItem *item;
+    while (*it) {
+        if ((*it)->type() == PROJECTCLIPTYPE) {
+            item = static_cast <ProjectItem *>(*it);
+            if (item->referencedClip()->getProperty("proxy") == proxyPath) {
+                setProxyStatus(item, status);
+            }
+        }
+        ++it;
+    }
 }
 
 void ProjectList::setProxyStatus(ProjectItem *item, PROXYSTATUS status)
index 1db7e2c84aa34538829e735b7bbe7305928a37ac..934856ef016c7a4b7a7c71b47b2636414fa30f5b 100644 (file)
@@ -240,6 +240,8 @@ public slots:
     void slotUpdateClipCut(QPoint p);
     void slotAddClipCut(const QString &id, int in, int out);
     void slotForceProcessing(const QString &id);
+    /** @brief Remove all instances of a proxy and delete the file. */
+    void slotDeleteProxy(const QString proxyPath);
 
 private:
     ProjectListView *m_listView;
@@ -268,10 +270,10 @@ private:
     QList <QString> m_thumbnailQueue;
     QAction *m_proxyAction;
     QStringList m_processingClips;
-    /** @brief Holds a list of ids for the clips that need to be proxied. */
-    QStringList m_proxyList;
-    /** @brief Holds a list of proxy clip that should be aborted. */
-    QStringList m_abortProxyId;
+    /** @brief Holds a list of proxy urls that should be aborted. */
+    QStringList m_abortProxy;
+    /** @brief Holds a list of proxy urls that are currently being created. */
+    QStringList m_processingProxy;
     
     void requestClipThumbnail(const QString id);
 
@@ -294,7 +296,7 @@ private:
     /** @brief Set the Proxy status on a clip. 
      * @param item The clip item to set status
      * @param status The proxy status (see definitions.h) */
-    void setProxyStatus(const QString id, PROXYSTATUS status);
+    void setProxyStatus(const QString proxyPath, PROXYSTATUS status);
     void setProxyStatus(ProjectItem *item, PROXYSTATUS status);
 
     void monitorItemEditing(bool enable);
@@ -329,15 +331,16 @@ private slots:
     /** @brief Add a sequence from the stopmotion widget. */
     void slotAddOrUpdateSequence(const QString frameName);
     /** @brief A proxy clip was created, update display. */
-    void slotGotProxy(const QString &id);
+    void slotGotProxy(const QString &proxyPath);
+    void slotGotProxy(ProjectItem *item);
     /** @brief Enable / disable proxy for current clip. */
     void slotProxyCurrentItem(bool doProxy);
     /** @brief Put clip in the proxy waiting list. */
     void slotCreateProxy(const QString id);
     /** @brief Stop creation of this clip's proxy. */
-    void slotAbortProxy(const QString id);
+    void slotAbortProxy(const QString id, const QString path);
     /** @brief Start creation of proxy clip. */
-    void slotGenerateProxy(const QString id);
+    void slotGenerateProxy(const QString destPath, const QString sourcePath, int clipType, int exif);
 
 signals:
     void clipSelected(DocClipBase *, QPoint zone = QPoint());
index 310a4ed1f8c81de62c918c4e328a744012452a91..8e750e5ddc66ba5fe3adfaa2e700ba5ab11f6e24 100644 (file)
@@ -696,6 +696,7 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int
 
     if ((!replaceProducer && xml.hasAttribute("file_hash")) || xml.hasAttribute("proxy")) {
         // Clip  already has all properties
+        if (replaceProducer) emit blockClipMonitor(clipId);
         emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer, selectClip);
         return;
     }
@@ -885,6 +886,7 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int
             metadataPropertyMap[ name.section('.', 0, -2)] = value;
     }
     producer->seek(0);
+    if (replaceProducer) emit blockClipMonitor(clipId);
     emit replyGetFileProperties(clipId, producer, filePropertyMap, metadataPropertyMap, replaceProducer, selectClip);
     // FIXME: should delete this to avoid a leak...
     //delete producer;
@@ -934,10 +936,13 @@ int Render::setProducer(Mlt::Producer *producer, int position)
     if (m_winid == -1) return -1;
 
     if (m_mltConsumer) {
-        m_mltConsumer->stop();
-    } else return -1;
+        if (!m_mltConsumer->is_stopped()) {
+            m_mltConsumer->stop();
+        }
+        m_mltConsumer->set("refresh", 0);
+    }
+    else return -1;
 
-    m_mltConsumer->purge();
     m_isBlocked = true;
     if (m_mltProducer) {
         m_mltProducer->set_speed(0);
@@ -945,6 +950,7 @@ int Render::setProducer(Mlt::Producer *producer, int position)
         m_mltProducer = NULL;
         emit stopped();
     }
+    blockSignals(true);
     if (producer) {
         m_mltProducer = new Mlt::Producer(producer->get_producer());
     } else m_mltProducer = m_blackClip->cut(0, 50);
@@ -956,6 +962,7 @@ int Render::setProducer(Mlt::Producer *producer, int position)
     int volume = KdenliveSettings::volume();
     m_mltProducer->set("meta.volume", (double)volume / 100);
     m_fps = m_mltProducer->get_fps();
+    blockSignals(false);
     int error = connectPlaylist();
 
     if (position != -1) {
index b892792330186a66778002fe8b53ee89d6c26f3f..93e69f35c3f5bf478cf49b474b19ad4adbd40b56 100644 (file)
@@ -361,6 +361,9 @@ signals:
      */
     void removeInvalidProxy(const QString &id, bool durationError);
     void refreshDocumentProducers(bool displayRatioChanged, bool fpsChanged);
+    
+    /** @brief If we will delete the producer, make sure to oause the monitor */
+    void blockClipMonitor(const QString);
 
     /** @brief A frame's image has to be shown.
      *