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

List:       kde-commits
Subject:    [kdenlive] src: Fix timeline thumbs flicker when fully zoomed #3247
From:       Jean-Baptiste Mardelle <jb () kdenlive ! org>
Date:       2014-03-31 21:18:02
Message-ID: E1WUjak-0007XJ-Az () scm ! kde ! org
[Download RAW message or body]

Git commit 66dc2e9275a238352874a4bd3a24cbbdc7361891 by Jean-Baptiste Mardelle.
Committed on 31/03/2014 at 21:17.
Pushed by mardelle into branch 'master'.

Fix timeline thumbs flicker when fully zoomed #3247

M  +4    -16   src/clipitem.cpp
M  +1    -1    src/clipmanager.cpp
M  +40   -14   src/kthumb.cpp
M  +2    -2    src/kthumb.h

http://commits.kde.org/kdenlive/66dc2e9275a238352874a4bd3a24cbbdc7361891

diff --git a/src/clipitem.cpp b/src/clipitem.cpp
index 993790a..2f5a152 100644
--- a/src/clipitem.cpp
+++ b/src/clipitem.cpp
@@ -101,6 +101,7 @@ ClipItem::ClipItem(DocClipBase *clip, const ItemInfo& info, \
double fps, double s  m_endThumbTimer.setSingleShot(true);
             connect(&m_endThumbTimer, SIGNAL(timeout()), this, \
                SLOT(slotGetEndThumb()));
             connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int,QImage)), this, \
SLOT(slotThumbReady(int,QImage))); +            connect(m_clip->thumbProducer(), \
                SIGNAL(thumbsCached()), this, SLOT(slotGotThumbsCache()));
             connect(m_clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
             if (generateThumbs) QTimer::singleShot(200, this, \
SLOT(slotFetchThumbs()));  }
@@ -818,26 +819,15 @@ void ClipItem::paint(QPainter *painter,
             if (thumbRect.isNull()) thumbRect = QRectF(0, 0, mapped.height() / \
m_startPix.height() * m_startPix.width(), mapped.height());  \
                thumbRect.moveTopRight(mapped.topRight());
             painter->drawPixmap(thumbRect, m_startPix, m_startPix.rect());
-            //const QPointF top = mapped.topRight() - QPointF(m_startPix.width() - \
                1, 0);
-            //painter->drawPixmap(top, m_startPix);
-            //QLineF l2(top.x(), mapped.top(), top.x(), mapped.bottom());
-            //painter->drawLine(l2);
         } else if (!m_endPix.isNull()) {
             if (thumbRect.isNull()) thumbRect = QRectF(0, 0, mapped.height() / \
m_endPix.height() * m_endPix.width(), mapped.height());  \
thumbRect.moveTopRight(mapped.topRight());  painter->drawPixmap(thumbRect, m_endPix, \
                m_endPix.rect());
-            //const QPointF top = mapped.topRight() - QPointF(m_endPix.width() - 1, \
                0);
-            //painter->drawPixmap(top, m_endPix);
-            //QLineF l2(top.x(), mapped.top(), top.x(), mapped.bottom());
-            //painter->drawLine(l2);
         }
         if (!m_startPix.isNull()) {
             if (thumbRect.isNull()) thumbRect = QRectF(0, 0, mapped.height() / \
m_startPix.height() * m_startPix.width(), mapped.height());  \
                thumbRect.moveTopLeft(mapped.topLeft());
             painter->drawPixmap(thumbRect, m_startPix, m_startPix.rect());
-            //painter->drawPixmap(mapped.topLeft(), m_startPix);
-            //QLineF l2(mapped.left() + m_startPix.width(), mapped.top(), \
                mapped.left() + m_startPix.width(), mapped.bottom());
-            //painter->drawLine(l2);
         }
 
         // if we are in full zoom, paint thumbnail for every frame
@@ -855,14 +845,13 @@ void ClipItem::paint(QPainter *painter,
             else {
 #if KDE_IS_VERSION(4,5,0)
                 if (m_clip && m_clip->thumbProducer()) {
-                    QString path = m_clip->fileURL().path() + '_';
                     QImage img;
                     QPen pen(Qt::white);
                     pen.setStyle(Qt::DotLine);
-                    QList <int> missing;
+                    QSet <int> missing;
                     for (int i = left; i <= right; ++i) {
-                        img = m_clip->thumbProducer()->findCachedThumb(path + \
                QString::number(i));
                         QPointF xpos = startPos + QPointF(FRAME_SIZE *(i - \
startOffset), 0); +                        img = \
m_clip->thumbProducer()->findCachedThumb(i);  if (img.isNull()) missing << i;
                         else {
                             painter->drawImage(xpos, img);
@@ -870,8 +859,8 @@ void ClipItem::paint(QPainter *painter,
                         painter->drawLine(xpos, xpos + QPointF(0, mapped.height()));
                     }
                     if (!missing.isEmpty()) {
+                        kDebug()<<"QUERYING PIXMAPS: "<<missing;
                         m_clip->thumbProducer()->queryIntraThumbs(missing);
-                        connect(m_clip->thumbProducer(), SIGNAL(thumbsCached()), \
this, SLOT(slotGotThumbsCache()));  }
                 }
 #endif
@@ -2175,7 +2164,6 @@ void ClipItem::updateGeometryKeyframes(QDomElement effect, int \
paramIndex, int w  
 void ClipItem::slotGotThumbsCache()
 {
-    disconnect(m_clip->thumbProducer(), SIGNAL(thumbsCached()), this, \
SLOT(slotGotThumbsCache()));  update();
 }
 
diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp
index 4b27929..76c6575 100644
--- a/src/clipmanager.cpp
+++ b/src/clipmanager.cpp
@@ -71,7 +71,7 @@ ClipManager::ClipManager(KdenliveDoc *doc, QGLWidget *glContext) :
 
 #if KDE_IS_VERSION(4,5,0)
     KImageCache::deleteCache("kdenlive-thumbs");
-    pixmapCache = new KImageCache("kdenlive-thumbs", 1000000);
+    pixmapCache = new KImageCache("kdenlive-thumbs", 10000000);
     pixmapCache->setEvictionPolicy(KSharedDataCache::EvictOldest);
 #endif
 }
diff --git a/src/kthumb.cpp b/src/kthumb.cpp
index 75c2c94..745aff6 100644
--- a/src/kthumb.cpp
+++ b/src/kthumb.cpp
@@ -42,6 +42,8 @@
 #include <QPainter>
 #include <QGLWidget>
 
+static QMutex m_intraMutex;
+
 KThumb::KThumb(ClipManager *clipManager, const KUrl &url, const QString &id, const \
QString &hash, QObject * parent) :  QObject(parent),
     m_url(url),
@@ -213,7 +215,7 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int \
displayWidth, int  return p;
     }
     
-    int ow = frameWidth;
+    int ow = displayWidth;//frameWidth;
     int oh = height;
     mlt_image_format format = mlt_image_rgb24a;
     //frame->set("progressive", "1");
@@ -228,7 +230,7 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int \
displayWidth, int  
     //const uchar* imagedata = frame->get_image(format, ow, oh);
     //QImage image(imagedata, ow, oh, QImage::Format_ARGB32_Premultiplied);
-    
+    return image.rgbSwapped();
     if (!image.isNull()) {
         if (ow > (2 * displayWidth)) {
             // there was a scaling problem, do it manually
@@ -365,12 +367,27 @@ void KThumb::slotCreateAudioThumbs()
 }
 
 #if KDE_IS_VERSION(4,5,0)
-void KThumb::queryIntraThumbs(const QList <int> &missingFrames)
+void KThumb::queryIntraThumbs(const QSet <int> &missingFrames)
 {
-    foreach (int i, missingFrames) {
-        if (!m_intraFramesQueue.contains(i)) m_intraFramesQueue.append(i);
+    m_intraMutex.lock();
+    if (m_intraFramesQueue.length() > 20) {
+        // trim query list
+        int maxsize = m_intraFramesQueue.length() - 10;
+        if (missingFrames.contains(m_intraFramesQueue.first())) {
+            for( int i = 0; i < maxsize; i ++ )
+                m_intraFramesQueue.removeLast();
+        }
+        else if (missingFrames.contains(m_intraFramesQueue.last())) {
+            for( int i = 0; i < maxsize; i ++ )
+                m_intraFramesQueue.removeFirst();
+        }
+        else m_intraFramesQueue.clear();
     }
+    QSet<int> set = m_intraFramesQueue.toSet();
+    set.unite(missingFrames);
+    m_intraFramesQueue = set.toList();
     qSort(m_intraFramesQueue);
+    m_intraMutex.unlock();
     if (!m_intra.isRunning()) {
         m_intra = QtConcurrent::run(this, &KThumb::slotGetIntraThumbs);
     }
@@ -380,30 +397,39 @@ void KThumb::slotGetIntraThumbs()
 {
     // We are in a new thread, so we need a new OpenGL context for the remainder of \
the function.  QGLWidget ctx(0, m_clipManager->getMainContext());
-    ctx.makeCurrent();
-
+    kDebug()<<"// STARTING INTR THB FOR: "<<m_intraFramesQueue;
     const int theight = KdenliveSettings::trackheight();
     const int frameWidth = (int)(theight * m_ratio + 0.5);
     const int displayWidth = (int)(theight * m_dar + 0.5);
     QString path = m_url.path() + '_';
     bool addedThumbs = false;
-
-    while (!m_intraFramesQueue.isEmpty()) {
-        int pos = m_intraFramesQueue.takeFirst();
-        if (!m_clipManager->pixmapCache->contains(path + QString::number(pos))) {
-            if (m_clipManager->pixmapCache->insertImage(path + QString::number(pos), \
getProducerFrame(pos, frameWidth, displayWidth, theight))) { +    int pos = 0;
+    while (true) {
+        m_intraMutex.lock();
+        if (m_intraFramesQueue.isEmpty()) {
+            m_intraMutex.unlock();
+            break;
+        }
+        pos = m_intraFramesQueue.takeFirst();
+        m_intraMutex.unlock();
+        const QString key = path + QString::number(pos);
+        if (!m_clipManager->pixmapCache->contains(key)) {
+            ctx.makeCurrent();
+            QImage img = getProducerFrame(pos, frameWidth, displayWidth, theight);
+            if (m_clipManager->pixmapCache->insertImage(key, img)) {
                 addedThumbs = true;
             }
             else kDebug()<<"// INSERT FAILD FOR: "<<pos;
         }
-        m_intraFramesQueue.removeAll(pos);
+        
     }
     if (addedThumbs) emit thumbsCached();
 }
 
-QImage KThumb::findCachedThumb(const QString &path)
+QImage KThumb::findCachedThumb(int pos)
 {
     QImage img;
+    const QString path = m_url.path() + '_' + QString::number(pos);
     m_clipManager->pixmapCache->findImage(path, &img);
     return img;
 }
diff --git a/src/kthumb.h b/src/kthumb.h
index 21b01fb..232397f 100644
--- a/src/kthumb.h
+++ b/src/kthumb.h
@@ -63,9 +63,9 @@ public:
     QImage extractImage(int frame, int width, int height);
 #if KDE_IS_VERSION(4,5,0)
     /** @brief Request thumbnails for the frame range. */
-    void queryIntraThumbs(const QList <int> &missingFrames);
+    void queryIntraThumbs(const QSet <int> &missingFrames);
     /** @brief Query cached thumbnail. */
-    QImage findCachedThumb(const QString &path);
+    QImage findCachedThumb(int pos);
 #endif
     void getThumb(int frame);
     void getGenericThumb(int frame, int height, int type);


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

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