]> git.sesse.net Git - kdenlive/commitdiff
Fix several crashes on document loading due to race condition in thumbnail generation
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 18 Oct 2008 18:36:50 +0000 (18:36 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 18 Oct 2008 18:36:50 +0000 (18:36 +0000)
svn path=/branches/KDE4/; revision=2477

src/clipitem.cpp
src/clipitem.h
src/customtrackview.cpp
src/customtrackview.h
src/mainwindow.cpp
src/projectlist.cpp
src/projectlist.h
src/trackview.cpp

index 615a3a84ad56e3b03b0d3bd16c8b409690ca0208..c645fe2acc025864ec2bb282df9ced4a5b02c44a 100644 (file)
@@ -40,7 +40,7 @@
 #include "kthumb.h"
 
 
-ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps)
+ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, bool generateThumbs)
         : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_startThumbRequested(false), m_endThumbRequested(false), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0), m_startPix(QPixmap()), m_endPix(QPixmap()) {
     setRect(0, 0, (info.endPos - info.startPos).frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() - 2));
     setPos((qreal) info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight()) + 1);
@@ -81,7 +81,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps)
 
         connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
         connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
-        QTimer::singleShot(200, this, SLOT(slotFetchThumbs()));
+        if (generateThumbs) QTimer::singleShot(200, this, SLOT(slotFetchThumbs()));
 
         /*if (m_clip->producer()) {
             videoThumbProducer.init(this, m_clip->producer(), KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio(), KdenliveSettings::trackheight());
index c1589cd74bcff254270fcba901514518e28681d9..84b89a47577f54a2f6d5f888cb907da84be546e5 100644 (file)
@@ -40,7 +40,7 @@ class ClipItem : public AbstractClipItem {
     Q_OBJECT
 
 public:
-    ClipItem(DocClipBase *clip, ItemInfo info, double fps);
+    ClipItem(DocClipBase *clip, ItemInfo info, double fps, bool generateThumbs = true);
     virtual ~ ClipItem();
     virtual void paint(QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
index 61721561de384fcd7d3987b8fce62b358aacfd5d..3a14029ba1ce7e3f4ba6ea878d8ad0bf60da5a76 100644 (file)
@@ -2334,7 +2334,7 @@ void CustomTrackView::setOutPoint() {
     m_commandStack->push(command);
 }
 
-void CustomTrackView::updateAllThumbs() {
+void CustomTrackView::slotUpdateAllThumbs() {
     QList<QGraphicsItem *> itemList = items();
     ClipItem *item;
     Transition *transitionitem;
@@ -2342,7 +2342,7 @@ void CustomTrackView::updateAllThumbs() {
         if (itemList.at(i)->type() == AVWIDGET) {
             item = static_cast <ClipItem *>(itemList.at(i));
             item->refreshClip();
-            //qApp->processEvents();
+            qApp->processEvents();
         }
     }
 }
index 75171dccda64cb664cf5293ed946c0c2e8691f34..269b49debd38f8f8e5f09d8404bd5b03886b1413 100644 (file)
@@ -98,7 +98,6 @@ public:
     void setDocumentModified();
     void setInPoint();
     void setOutPoint();
-    void updateAllThumbs();
 
 public slots:
     void setCursorPos(int pos, bool seek = true);
@@ -127,6 +126,7 @@ public slots:
     void copyClip();
     void pasteClip();
     void pasteClipEffects();
+    void slotUpdateAllThumbs();
 
 protected:
     virtual void drawBackground(QPainter * painter, const QRectF & rect);
index f0e54c121e518d1d965bfc6677f1ea26bfd2a87d..40a4d2c18b4f917fa954ec82cb9349a0e8da5389 100644 (file)
@@ -1172,7 +1172,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
         m_activeDocument->backupMltPlaylist();
         if (m_activeTimeline) {
             disconnect(m_projectMonitor, SIGNAL(renderPosition(int)), m_activeTimeline, SLOT(moveCursorPos(int)));
-            disconnect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), trackView, SLOT(slotSetZone(QPoint)));
+            disconnect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), m_activeTimeline, SLOT(slotSetZone(QPoint)));
             disconnect(m_projectMonitor, SIGNAL(durationChanged(int)), m_activeTimeline, SLOT(setDuration(int)));
             disconnect(m_projectList, SIGNAL(projectModified()), m_activeDocument, SLOT(setModified()));
             disconnect(m_activeDocument, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated()));
@@ -1194,13 +1194,14 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
             disconnect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
             disconnect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
             disconnect(effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
-            disconnect(effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
+            disconnect(effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), m_activeTimeline->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
             disconnect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
             disconnect(effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
-            disconnect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
-            disconnect(transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int)));
+            disconnect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), m_activeTimeline->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
+            disconnect(transitionConfig, SIGNAL(seekTimeline(int)), m_activeTimeline->projectView() , SLOT(setCursorPos(int)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
-            disconnect(trackView, SIGNAL(zoneMoved(int, int)), m_projectMonitor, SLOT(slotZoneMoved(int, int)));
+            disconnect(m_activeTimeline, SIGNAL(zoneMoved(int, int)), m_projectMonitor, SLOT(slotZoneMoved(int, int)));
+            disconnect(m_projectList, SIGNAL(loadingIsOver()), m_activeTimeline->projectView(), SLOT(slotUpdateAllThumbs()));
             effectStack->clear();
         }
         m_activeDocument->setRenderer(NULL);
@@ -1255,6 +1256,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
 
     connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
     connect(trackView, SIGNAL(zoneMoved(int, int)), m_projectMonitor, SLOT(slotZoneMoved(int, int)));
+    connect(m_projectList, SIGNAL(loadingIsOver()), trackView->projectView(), SLOT(slotUpdateAllThumbs()));
 
     trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu);
     m_activeTimeline = trackView;
@@ -1263,7 +1265,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     m_commandStack->setActiveStack(doc->commandStack());
     KdenliveSettings::setProject_display_ratio(doc->dar());
     m_projectList->updateAllClips();
-    trackView->projectView()->updateAllThumbs();
     doc->clipManager()->checkAudioThumbs();
 
     //m_overView->setScene(trackView->projectScene());
index 95716709500699a613ca137711ac3e7408b0b20e..d8d30f911f25632df6a555379a7ea0447562f1bf 100644 (file)
@@ -53,7 +53,7 @@
 #include "projectlistview.h"
 
 ProjectList::ProjectList(QWidget *parent)
-        : QWidget(parent), m_render(NULL), m_fps(-1), m_commandStack(NULL), m_selectedItem(NULL), m_infoQueue(QMap <QString, QDomElement> ()), m_thumbnailQueue(QList <QString> ()) {
+        : QWidget(parent), m_render(NULL), m_fps(-1), m_commandStack(NULL), m_selectedItem(NULL), m_infoQueue(QMap <QString, QDomElement> ()), m_thumbnailQueue(QList <QString> ()), m_refreshed(false) {
 
     QWidget *vbox = new QWidget;
     listView = new ProjectListView(this);;
@@ -387,7 +387,6 @@ void ProjectList::updateAllClips() {
                 requestClipInfo(clip->toXML(), clip->getId());
             } else {
                 requestClipThumbnail(item->clipId());
-                //slotRefreshClipThumbnail(item, false);
                 item->changeDuration(item->referencedClip()->producer()->get_playtime());
             }
             item->setData(1, UsageRole, QString::number(item->numReferences()));
@@ -395,6 +394,7 @@ void ProjectList::updateAllClips() {
         }
         ++it;
     }
+    QTimer::singleShot(500, this, SLOT(slotCheckForEmptyQueue()));
 }
 
 void ProjectList::slotAddClip(QUrl givenUrl, QString group) {
@@ -512,7 +512,11 @@ void ProjectList::slotAddTitleClip() {
 
 void ProjectList::setDocument(KdenliveDoc *doc) {
     listView->clear();
+    m_thumbnailQueue.clear();
+    m_infoQueue.clear();
+    m_refreshed = false;
     QList <DocClipBase*> list = doc->clipManager()->documentClipList();
+    listView->blockSignals(true);
     for (int i = 0; i < list.count(); i++) {
         slotAddClip(list.at(i), false);
     }
@@ -523,6 +527,7 @@ void ProjectList::setDocument(KdenliveDoc *doc) {
     m_doc = doc;
     QTreeWidgetItem *first = listView->topLevelItem(0);
     if (first) listView->setCurrentItem(first);
+    listView->blockSignals(false);
     m_toolbar->setEnabled(true);
 }
 
@@ -540,6 +545,12 @@ QDomElement ProjectList::producersList() {
     return prods;
 }
 
+void ProjectList::slotCheckForEmptyQueue() {
+    if (!m_refreshed && m_thumbnailQueue.isEmpty() && m_infoQueue.isEmpty()) {
+        m_refreshed = true;
+        emit loadingIsOver();
+    } else QTimer::singleShot(500, this, SLOT(slotCheckForEmptyQueue()));
+}
 
 void ProjectList::requestClipThumbnail(const QString &id) {
     m_thumbnailQueue.append(id);
@@ -547,7 +558,9 @@ void ProjectList::requestClipThumbnail(const QString &id) {
 }
 
 void ProjectList::slotProcessNextThumbnail() {
-    if (m_thumbnailQueue.isEmpty()) return;
+    if (m_thumbnailQueue.isEmpty()) {
+        return;
+    }
     slotRefreshClipThumbnail(m_thumbnailQueue.takeFirst(), false);
 }
 
@@ -559,6 +572,7 @@ void ProjectList::slotRefreshClipThumbnail(const QString &clipId, bool update) {
 
 void ProjectList::slotRefreshClipThumbnail(ProjectItem *item, bool update) {
     if (item) {
+        if (!item->referencedClip()) return;
         int height = 50;
         int width = (int)(height  * m_render->dar());
         QPixmap pix = item->referencedClip()->thumbProducer()->extractImage(item->referencedClip()->getClipThumbFrame(), width, height);
index 9fa7cb1b1c9403efa72e4563eef7d6f432b17f93..e1510e271d5710a18d7ddad0e61a5c2415bb43f9 100644 (file)
@@ -140,6 +140,7 @@ private:
     KdenliveDoc *m_doc;
     ItemDelegate *m_listViewDelegate;
     ProjectItem *m_selectedItem;
+    bool m_refreshed;
     QMap <QString, QDomElement> m_infoQueue;
     void requestClipInfo(const QDomElement xml, const QString id);
     QList <QString> m_thumbnailQueue;
@@ -160,6 +161,7 @@ private slots:
     void slotUpdateClipProperties(ProjectItem *item, QMap <QString, QString> properties);
     void slotProcessNextClipInQueue();
     void slotProcessNextThumbnail();
+    void slotCheckForEmptyQueue();
     //void slotShowMenu(const QPoint &pos);
 
 signals:
@@ -168,6 +170,7 @@ signals:
     void receivedClipDuration(const QString &, int);
     void showClipProperties(DocClipBase *);
     void projectModified();
+    void loadingIsOver();
 };
 
 #endif
index 741d712bb134d703bf3ab66d019a4477c35fa1aa..13772ca0630a3823b9db3bc2cf6cd4880b6a4a8e 100644 (file)
@@ -362,7 +362,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) {
                 clipinfo.cropStart = GenTime(in, m_doc->fps());
                 clipinfo.track = ix;
                 //kDebug() << "// INSERTING CLIP: " << in << "x" << out << ", track: " << ix << ", ID: " << id << ", SCALE: " << m_scale << ", FPS: " << m_doc->fps();
-                ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps());
+                ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps(), false);
                 if (hasSpeedAttribute) item->setSpeed(speed);
                 m_scene->addItem(item);
                 clip->addReference();