[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdenlive/Applications/16.12] src: Fix crash & corruption on dragging multiple clips in timeline, fi
From:       Jean-Baptiste Mardelle <null () kde ! org>
Date:       2017-03-06 22:57:33
Message-ID: E1cl1ZN-0004eL-Hc () code ! kde ! org
[Download RAW message or body]

Git commit c17302f7eacbf08bb6a2c77c5a5e90d657d1b926 by Jean-Baptiste Mardelle.
Committed on 06/03/2017 at 22:57.
Pushed by mardelle into branch 'Applications/16.12'.

Fix crash & corruption on dragging multiple clips in timeline, fix thread warning on \
monitor refresh

M  +4    -3    src/bin/bin.cpp
M  +1    -0    src/mainwindow.cpp
M  +3    -6    src/mltcontroller/bincontroller.cpp
M  +16   -9    src/timeline/clip.cpp
M  +5    -3    src/timeline/customtrackview.cpp
M  +2    -2    src/timeline/customtrackview.h

https://commits.kde.org/kdenlive/c17302f7eacbf08bb6a2c77c5a5e90d657d1b926

diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp
index 3804ac26c..ae09a91e8 100644
--- a/src/bin/bin.cpp
+++ b/src/bin/bin.cpp
@@ -864,7 +864,6 @@ void Bin::slotDeleteClip()
 	if (!isChild) {
             if (!usedClips && current->refCount() > 0) {
                 usedClips = true;
-                
             }
             clipIds << current->clipId();
         }
@@ -910,7 +909,7 @@ void Bin::slotReloadClip()
                         }
                     }
                 }
-            }            
+            }
             QDomDocument doc;
             QDomElement xml = currentItem->toXml(doc);
             qDebug()<<"*****************\n"<<doc.toString()<<"\n******************";
@@ -1951,7 +1950,9 @@ void Bin::slotProducerReady(requestClipInfo info, \
                ClipController *controller)
                     m_doc->slotProxyCurrentItem(true, QList <ProjectClip *>() << \
clip);  }
             }
-        } else emit producerReady(info.clipId);
+        } else {
+            emit producerReady(info.clipId);
+        }
         QString currentClip = m_monitor->activeClipId();
         if (currentClip.isEmpty()) {
             //No clip displayed in monitor, check if item is selected
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 005e81ffa..db7ca368b 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -165,6 +165,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, \
const QString &  qRegisterMetaType<stringMap> ("stringMap");
     qRegisterMetaType<audioByteArray> ("audioByteArray");
     qRegisterMetaType< QVector <int> > ();
+    qRegisterMetaType< QList<ItemInfo> > ("QList<ItemInfo>");
     qRegisterMetaType<QDomElement> ("QDomElement");
     qRegisterMetaType<requestClipInfo> ("requestClipInfo");
     qRegisterMetaType<MltVideoProfile> ("MltVideoProfile");
diff --git a/src/mltcontroller/bincontroller.cpp \
b/src/mltcontroller/bincontroller.cpp index ced6f767f..dbacf161e 100644
--- a/src/mltcontroller/bincontroller.cpp
+++ b/src/mltcontroller/bincontroller.cpp
@@ -21,6 +21,7 @@
 #include "bincontroller.h"
 #include "clipcontroller.h"
 #include "kdenlivesettings.h"
+#include "timeline/clip.h"
 
 #include <QFileInfo>
 
@@ -341,12 +342,8 @@ bool BinController::removeBinClip(const QString &id)
 
 Mlt::Producer *BinController::cloneProducer(Mlt::Producer &original)
 {
-    QString service = QString::fromLatin1(original.get("mlt_service"));
-    QString resource = QString::fromLatin1(original.get("resource"));
-    Mlt::Producer *clone = new Mlt::Producer(*original.profile(), \
                service.toUtf8().constData(), resource.toUtf8().constData());
-    Mlt::Properties original_props(original.get_properties());
-    Mlt::Properties cloneProps(clone->get_properties());
-    cloneProps.inherit(original_props);
+    Clip clp(original);
+    Mlt::Producer *clone = clp.clone();
     return clone;
 }
 
diff --git a/src/timeline/clip.cpp b/src/timeline/clip.cpp
index 11d25acc4..82916863b 100644
--- a/src/timeline/clip.cpp
+++ b/src/timeline/clip.cpp
@@ -23,7 +23,8 @@
 
 #include "clip.h"
 #include <mlt++/Mlt.h>
-
+#include <QDomDocument>
+#include <QDebug>
 
 Clip::Clip(Mlt::Producer &producer) : QObject(),
     m_producer(producer)
@@ -162,8 +163,9 @@ const QByteArray Clip::xml()
     Mlt::Consumer c(*m_producer.profile(), "xml", "string");
     Mlt::Service s(m_producer.get_service());
     int ignore = s.get_int("ignore_points");
-    if (ignore) s.set("ignore_points", 0);
-    if (s.get_int("ignore_points")) s.set("ignore_points", 0);
+    if (ignore) {
+        s.set("ignore_points", 0);
+    }
     c.connect(s);
     c.set("time_format", "frames");
     c.set("no_meta", 1);
@@ -177,12 +179,17 @@ const QByteArray Clip::xml()
 
 Mlt::Producer *Clip::clone()
 {
-    QString service = QString::fromLatin1(m_producer.get("mlt_service"));
-    QString resource = QString::fromLatin1(m_producer.get("resource"));
-    Mlt::Producer *clone = new Mlt::Producer(*m_producer.profile(), \
                service.toUtf8().constData(), resource.toUtf8().constData());
-    Mlt::Properties original(m_producer.get_properties());
-    Mlt::Properties cloneProps(clone->get_properties());
-    cloneProps.inherit(original);
+    QByteArray prodXml = xml();
+    //HACK: currently the MLT xml producer, when parsing a <profile>, does change \
the global profile accordingly. +    // causing crash on threaded calls. To avoid \
this, we discard the profile info from our xml +    QDomDocument doc;
+    doc.setContent(prodXml, true);
+    QDomNodeList profiles = doc.documentElement().elementsByTagName("profile");
+    if (!profiles.isEmpty()) {
+        QDomNode profile = profiles.item(0);
+        doc.documentElement().removeChild(profile);
+    }
+    Mlt::Producer *clone = new Mlt::Producer(*m_producer.profile(), "xml-string", \
doc.toByteArray().constData());  return clone;
 }
 
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index 4cf868eaf..11e26f0e7 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -7210,8 +7210,9 @@ void CustomTrackView::monitorRefresh(QList <ItemInfo> range, \
bool invalidateRang  if (invalidateRange)
             m_timeline->invalidateRange(range.at(i));
     }
-    if (refreshMonitor)
+    if (refreshMonitor) {
         m_document->renderer()->doRefresh();
+    }
 }
 
 void CustomTrackView::monitorRefresh(ItemInfo range, bool invalidateRange)
@@ -7938,8 +7939,9 @@ void CustomTrackView::slotReplaceTimelineProducer(const QString \
&id)  Mlt::Producer *sprod = i.value();
 	m_document->renderer()->storeSlowmotionProducer(i.key() + url, sprod, true);
     }
-    if (!toUpdate.isEmpty())
-        monitorRefresh(toUpdate, true);
+    if (!toUpdate.isEmpty()) {
+        QMetaObject::invokeMethod(this, "monitorRefresh", Qt::QueuedConnection, \
Q_ARG(QList <ItemInfo>, toUpdate), Q_ARG(bool, true)); +    }
     m_timeline->refreshTractor();
 }
 
diff --git a/src/timeline/customtrackview.h b/src/timeline/customtrackview.h
index d7b9f5f6f..ba2a27b5f 100644
--- a/src/timeline/customtrackview.h
+++ b/src/timeline/customtrackview.h
@@ -216,8 +216,6 @@ public:
     /** @brief Returns last requested seeking pos, or current cursor position. */
     int seekPosition() const;
 
-    /** @brief Trigger a monitor refresh. */
-    void monitorRefresh(QList <ItemInfo> range, bool invalidateRange = false);
     void monitorRefresh(bool invalidateRange = false);
     /** @brief Trigger a monitor refresh if timeline cursor is inside range. */
     void monitorRefresh(ItemInfo range, bool invalidateRange = false);
@@ -350,6 +348,8 @@ public slots:
     void slotTransitionUpdated(Transition *, QDomElement);
     void slotSwitchTrackLock(int ix, bool enable, bool applyToAll = false);
     void slotUpdateClip(const QString &clipId, bool reload = true);
+    /** @brief Trigger a monitor refresh. */
+    void monitorRefresh(QList <ItemInfo> range, bool invalidateRange = false);
 
     bool addGuide(const GenTime &pos, const QString &comment, bool loadingProject = \
false);  


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic