QLineF l2(mapped.left() + m_startPix.width(), mapped.top(), mapped.left() + m_startPix.width(), mapped.bottom());
painter->drawLine(l2);
}
- if (painter->matrix().m11() == FRAME_SIZE) {
+ if (painter->matrix().m11() == FRAME_SIZE && m_clip->thumbProducer() && clipType() != COLOR && clipType() != AUDIO && !m_audioOnly) {
int offset = (m_info.startPos - m_info.cropStart).frames(m_fps);
- int left = qMax((int) m_info.startPos.frames(m_fps) + 1, (int) mapToScene(exposed.left(), 0).x());
- int right = qMin((int)(m_info.startPos + m_info.cropDuration).frames(m_fps) - 1, (int) mapToScene(exposed.right(), 0).x());
- doGetIntraThumbs(painter, mapped.topLeft(), m_info.cropStart.frames(m_fps), left - offset, right - offset);
+ int left = qMax((int) m_info.startPos.frames(m_fps) + 1, (int) mapToScene(exposed.left(), 0).x()) - offset;
+ int right = qMin((int)(m_info.startPos + m_info.cropDuration).frames(m_fps) - 1, (int) mapToScene(exposed.right(), 0).x()) - offset;
+ QPointF startPos = mapped.topLeft();
+ int twidth = FRAME_SIZE;
+ int startOffset = m_info.cropStart.frames(m_fps);
+ if (clipType() == IMAGE || clipType() == TEXT) {
+ for (int i = left; i <= right; i++) {
+ painter->drawPixmap(startPos + QPointF(twidth *(i - startOffset), 0), m_startPix);
+ }
+ }
+ else {
+#if KDE_IS_VERSION(4,5,0)
+ m_clip->thumbProducer()->queryIntraThumbs(left, right);
+ connect(m_clip->thumbProducer(), SIGNAL(thumbsCached()), this, SLOT(slotGotThumbsCache()));
+ QString path = m_clip->fileURL().path() + "%";
+ for (int i = left; i <= right; i++) {
+ painter->drawImage(startPos + QPointF(twidth *(i - startOffset), 0), m_clip->thumbProducer()->findCachedThumb(path + QString::number(i)));
+ }
+#endif
+ }
}
painter->setPen(Qt::black);
}
if (!m_keyframes.contains(m_selectedKeyframe)) m_selectedKeyframe = -1;
}
-void ClipItem::doGetIntraThumbs(QPainter *painter, const QPointF startPos, int offset, int start, int end)
+/*void ClipItem::slotGetIntraThumbs(CustomTrackView *view, int start, int end)
{
- if (!m_clip->thumbProducer() || clipType() == COLOR) return;
- if (scene() && scene()->views().isEmpty()) return;
- CustomTrackView *view = (CustomTrackView *) scene()->views()[0];
- if (view == NULL) return;
const int theight = KdenliveSettings::trackheight();
const int twidth = FRAME_SIZE;
-
- if (clipType() == IMAGE || clipType() == TEXT) {
- for (int i = start; i <= end; i++)
- painter->drawPixmap(startPos + QPointF(twidth *(i - offset), 0), m_startPix);
- }
+ QString path = m_clip->fileURL().path() + "%";
QPixmap p;
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)) {
+ if (!view->m_pixmapCache->contains(path + QString::number(i))) {
p = m_clip->extractImage(i, twidth, theight);
- view->m_pixmapCache->insertPixmap(m_clip->fileURL().path() + "%" + QString::number(i), p);
+ view->m_pixmapCache->insertPixmap(path + QString::number(i), p);
}
#else
- if (!view->m_pixmapCache->find(m_clip->fileURL().path() + "%" + QString::number(i), p)) {
+ if (!view->m_pixmapCache->find(path + QString::number(i), p)) {
p = m_clip->extractImage(i, twidth, theight);
- view->m_pixmapCache->insert(m_clip->fileURL().path() + "%" + QString::number(i), p);
+ view->m_pixmapCache->insert(path + QString::number(i), p);
}
#endif
- painter->drawPixmap(startPos + QPointF(twidth *(i - offset), 0), p);
}
-}
+ update();
+}*/
QList <int> ClipItem::updatePanZoom(int width, int height, int cut)
{
param.setAttribute("value", geometry.serialise(cropStart().frames(m_fps), (cropStart() + cropDuration()).frames(m_fps) - 1));
}
+void ClipItem::slotGotThumbsCache()
+{
+ disconnect(m_clip->thumbProducer(), SIGNAL(thumbsCached()), this, SLOT(slotGotThumbsCache()));
+ update();
+}
+
#include "clipitem.moc"
QPixmap m_videoPix;
QPixmap m_audioPix;
- void doGetIntraThumbs(QPainter *painter, const QPointF startPos, int offset, int start, int end);
private slots:
void slotGetStartThumb();
void slotSetStartThumb(QImage img);
void slotSetEndThumb(QImage img);
void slotThumbReady(int frame, QImage img);
+ /** @brief The thumbnailer has finished to cache all required thumbs. */
+ void slotGotThumbsCache();
public slots:
void slotFetchThumbs();
connect(&m_fileWatcher, SIGNAL(deleted(const QString &)), this, SLOT(slotClipMissing(const QString &)));
connect(&m_fileWatcher, SIGNAL(created(const QString &)), this, SLOT(slotClipAvailable(const QString &)));
connect(&m_modifiedTimer, SIGNAL(timeout()), this, SLOT(slotProcessModifiedClips()));
+
+#if KDE_IS_VERSION(4,5,0)
+ pixmapCache = new KImageCache("kdenlive-thumbs", 1000000);
+#endif
}
ClipManager::~ClipManager()
m_generatingAudioId.clear();
qDeleteAll(m_clipList);
m_clipList.clear();
+#if KDE_IS_VERSION(4,5,0)
+ delete pixmapCache;
+#endif
}
void ClipManager::clear()
m_clipList.clear();
m_clipIdCounter = 1;
m_folderIdCounter = 1;
+#if KDE_IS_VERSION(4,5,0)
+ pixmapCache->clear();
+#endif
}
void ClipManager::checkAudioThumbs()
#include <KUndoStack>
#include <KDirWatch>
#include <klocale.h>
+#include <kdeversion.h>
+
+#if KDE_IS_VERSION(4,5,0)
+#include <KImageCache>
+#endif
+
#include "gentime.h"
#include "definitions.h"
QDomElement groupsXml() const;
int clipsCount() const;
+#if KDE_IS_VERSION(4,5,0)
+ KImageCache* pixmapCache;
+#endif
+
private slots:
/** A clip was externally modified, monitor for more changes and prepare for reload */
void slotClipModified(const QString &path);
m_activeTrackBrush = KStatefulBrush(KColorScheme::View, KColorScheme::ActiveBackground, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
-#if KDE_IS_VERSION(4,5,0)
- m_pixmapCache = new KImageCache("kdenlive-thumbs", 1000000);
-#else
- m_pixmapCache = new KPixmapCache("kdenlive-thumbs");
-#endif
-
m_animationTimer = new QTimeLine(800);
m_animationTimer->setFrameRange(0, 5);
m_animationTimer->setUpdateInterval(100);
qDeleteAll(m_guides);
m_guides.clear();
m_waitingThumbs.clear();
- delete m_pixmapCache;
delete m_animationTimer;
}
#define CUSTOMTRACKVIEW_H
#include <kdeversion.h>
-#if KDE_IS_VERSION(4,5,0)
-#include <KImageCache>
-#else
-#include <KPixmapCache>
-#endif
-
#include <KColorScheme>
#include <QGraphicsView>
void clearSelection();
void editItemDuration();
void buildGuidesMenu(QMenu *goMenu) const;
-#if KDE_IS_VERSION(4,5,0)
- KImageCache* m_pixmapCache;
-#else
- KPixmapCache* m_pixmapCache;
-#endif
/** update the timeline objects when palette changes */
void updatePalette();
/** @brief Returns true if a track has audio data on it.
KThumb::~KThumb()
{
m_requestedThumbs.clear();
+ m_intraFramesQueue.clear();
if (m_audioThumbProducer.isRunning()) {
m_stopAudioThumbs = true;
m_audioThumbProducer.waitForFinished();
slotAudioThumbOver();
}
m_future.waitForFinished();
+ m_intra.waitForFinished();
}
void KThumb::setProducer(Mlt::Producer *producer)
{
m_requestedThumbs.clear();
+ m_intraFramesQueue.clear();
m_future.waitForFinished();
+ m_intra.waitForFinished();
m_producer = producer;
// FIXME: the profile() call leaks an object, but trying to free
// it leads to a double-free in Profile::~Profile()
return pix;
}
-
//static
QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int height)
{
m_clipManager->askForAudioThumb(id);
}
+#if KDE_IS_VERSION(4,5,0)
+void KThumb::queryIntraThumbs(int start, int end)
+{
+ for (int i = start; i <= end; i++) {
+ if (!m_intraFramesQueue.contains(i)) m_intraFramesQueue.append(i);
+ }
+ qSort(m_intraFramesQueue);
+ if (!m_intra.isRunning()) m_intra = QtConcurrent::run(this, &KThumb::slotGetIntraThumbs);
+}
+
+void KThumb::slotGetIntraThumbs()
+{
+ int theight = KdenliveSettings::trackheight();
+ int twidth = FRAME_SIZE;
+ QString path = m_url.path() + "%";
+ QImage img;
+
+ while (!m_intraFramesQueue.isEmpty()) {
+ int pos = m_intraFramesQueue.takeFirst();
+ if (!m_clipManager->pixmapCache->contains(path + QString::number(pos))) {
+ m_clipManager->pixmapCache->insertImage(path + QString::number(pos), getFrame(m_producer, pos, twidth, theight));
+ }
+ m_intraFramesQueue.removeAll(pos);
+ }
+ emit thumbsCached();
+}
+
+QImage KThumb::findCachedThumb(const QString path)
+{
+ QImage img;
+ m_clipManager->pixmapCache->findImage(path, &img);
+ return img;
+}
+#endif
#include "kthumb.moc"
#include <QFuture>
#include <KUrl>
+#include <kdeversion.h>
#include <mlt++/Mlt.h>
void updateThumbUrl(const QString &hash);
void extractImage(int frame, int frame2);
QPixmap extractImage(int frame, int width, int height);
+#if KDE_IS_VERSION(4,5,0)
+ /** @brief Request thumbnails for the frame range. */
+ void queryIntraThumbs(int start, int end);
+ /** @brief Query cached thumbnail. */
+ QImage findCachedThumb(const QString path);
+#endif
public slots:
void updateClipUrl(KUrl url, const QString &hash);
private slots:
void slotAudioThumbOver();
void slotCreateAudioThumbs();
+#if KDE_IS_VERSION(4,5,0)
+ /** @brief Fetch all requested frames. */
+ void slotGetIntraThumbs();
+#endif
private:
QFuture<void> m_audioThumbProducer;
ClipManager *m_clipManager;
QString m_id;
QList <int> m_requestedThumbs;
+ /** @brief Controls the thumbnails process. */
QFuture<void> m_future;
+ /** @brief Controls the intra frames thumbnails process (cached thumbnails). */
+ QFuture<void> m_intra;
QFile m_audioThumbFile;
bool m_stopAudioThumbs;
double m_frame;
int m_frequency;
int m_channels;
int m_arrayWidth;
+ /** @brief List of frame numbers from which we want to extract thumbnails. */
+ QList <int> m_intraFramesQueue;
void doGetThumbs();
signals:
void thumbReady(int, QImage);
void mainThumbReady(const QString &, QPixmap);
void audioThumbReady(QMap <int, QMap <int, QByteArray> >);
+ /** @brief We have finished caching all requested thumbs. */
+ void thumbsCached();
};
#endif