Git commit 66dc2e9275a238352874a4bd3a24cbbdc7361891 by Jean-Baptiste Mardel= le. 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& i= nfo, double fps, double s m_endThumbTimer.setSingleShot(true); connect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGe= tEndThumb())); 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(slotGotAudi= oData())); if (generateThumbs) QTimer::singleShot(200, this, SLOT(slotFet= chThumbs())); } @@ -818,26 +819,15 @@ void ClipItem::paint(QPainter *painter, if (thumbRect.isNull()) thumbRect =3D QRectF(0, 0, mapped.heig= ht() / m_startPix.height() * m_startPix.width(), mapped.height()); thumbRect.moveTopRight(mapped.topRight()); painter->drawPixmap(thumbRect, m_startPix, m_startPix.rect()); - //const QPointF top =3D 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 =3D QRectF(0, 0, mapped.heig= ht() / m_endPix.height() * m_endPix.width(), mapped.height()); thumbRect.moveTopRight(mapped.topRight()); painter->drawPixmap(thumbRect, m_endPix, m_endPix.rect()); - //const QPointF top =3D mapped.topRight() - QPointF(m_endPix.w= idth() - 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 =3D QRectF(0, 0, mapped.heig= ht() / 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 =3D m_clip->fileURL().path() + '_'; QImage img; QPen pen(Qt::white); pen.setStyle(Qt::DotLine); - QList missing; + QSet missing; for (int i =3D left; i <=3D right; ++i) { - img =3D m_clip->thumbProducer()->findCachedThumb(p= ath + QString::number(i)); QPointF xpos =3D startPos + QPointF(FRAME_SIZE *(i= - startOffset), 0); + img =3D 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.h= eight())); } if (!missing.isEmpty()) { + kDebug()<<"QUERYING PIXMAPS: "<thumbProducer()->queryIntraThumbs(missing); - connect(m_clip->thumbProducer(), SIGNAL(thumbsCach= ed()), this, SLOT(slotGotThumbsCache())); } } #endif @@ -2175,7 +2164,6 @@ void ClipItem::updateGeometryKeyframes(QDomElement ef= fect, 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 *glC= ontext) : = #if KDE_IS_VERSION(4,5,0) KImageCache::deleteCache("kdenlive-thumbs"); - pixmapCache =3D new KImageCache("kdenlive-thumbs", 1000000); + pixmapCache =3D 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 #include = +static QMutex m_intraMutex; + KThumb::KThumb(ClipManager *clipManager, const KUrl &url, const QString &i= d, const QString &hash, QObject * parent) : QObject(parent), m_url(url), @@ -213,7 +215,7 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWid= th, int displayWidth, int return p; } = - int ow =3D frameWidth; + int ow =3D displayWidth;//frameWidth; int oh =3D height; mlt_image_format format =3D mlt_image_rgb24a; //frame->set("progressive", "1"); @@ -228,7 +230,7 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWid= th, int displayWidth, int = //const uchar* imagedata =3D 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 &missingFrames) +void KThumb::queryIntraThumbs(const QSet &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 =3D m_intraFramesQueue.length() - 10; + if (missingFrames.contains(m_intraFramesQueue.first())) { + for( int i =3D 0; i < maxsize; i ++ ) + m_intraFramesQueue.removeLast(); + } + else if (missingFrames.contains(m_intraFramesQueue.last())) { + for( int i =3D 0; i < maxsize; i ++ ) + m_intraFramesQueue.removeFirst(); + } + else m_intraFramesQueue.clear(); } + QSet set =3D m_intraFramesQueue.toSet(); + set.unite(missingFrames); + m_intraFramesQueue =3D set.toList(); qSort(m_intraFramesQueue); + m_intraMutex.unlock(); if (!m_intra.isRunning()) { m_intra =3D 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 rem= ainder of the function. QGLWidget ctx(0, m_clipManager->getMainContext()); - ctx.makeCurrent(); - + kDebug()<<"// STARTING INTR THB FOR: "<pixmapCache->contains(path + QString::number(p= os))) { - if (m_clipManager->pixmapCache->insertImage(path + QString::nu= mber(pos), getProducerFrame(pos, frameWidth, displayWidth, theight))) { + int pos =3D 0; + while (true) { + m_intraMutex.lock(); + if (m_intraFramesQueue.isEmpty()) { + m_intraMutex.unlock(); + break; + } + pos =3D m_intraFramesQueue.takeFirst(); + m_intraMutex.unlock(); + const QString key =3D path + QString::number(pos); + if (!m_clipManager->pixmapCache->contains(key)) { + ctx.makeCurrent(); + QImage img =3D getProducerFrame(pos, frameWidth, displayWidth,= theight); + if (m_clipManager->pixmapCache->insertImage(key, img)) { addedThumbs =3D true; } else kDebug()<<"// INSERT FAILD FOR: "<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 &missingFrames); + void queryIntraThumbs(const QSet &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);