Commit 8b96890a authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Limit number of threads started for timeline thumbnails

parent 24d12a16
......@@ -97,6 +97,8 @@ ProjectClip::~ProjectClip()
{
// controller is deleted in bincontroller
abortAudioThumbs();
m_requestedThumbs.clear();
m_thumbThread.waitForFinished();
delete m_thumbsProducer;
}
......@@ -724,24 +726,41 @@ QVariant ProjectClip::data(DataType type) const
}
void ProjectClip::slotExtractImage(QList <int> frames)
{
QMutexLocker lock(&m_thumbMutex);
for (int i = 0; i < frames.count(); i++) {
if (!m_requestedThumbs.contains(frames.at(i))) {
m_requestedThumbs << frames.at(i);
}
}
qSort(m_requestedThumbs);
if (!m_thumbThread.isRunning()) {
m_thumbThread = QtConcurrent::run(this, &ProjectClip::doExtractImage);
}
}
void ProjectClip::doExtractImage()
{
Mlt::Producer *prod = thumbProducer();
if (prod == NULL || !prod->is_valid()) return;
int fullWidth = (int)((double) 150 * prod->profile()->dar() + 0.5);
QDir thumbFolder(bin()->projectFolder().path() + "/thumbs/");
for (int i = 0; i < frames.count(); i++) {
int pos = frames.at(i);
int max = prod->get_length();
int pos;
while (!m_requestedThumbs.isEmpty()) {
m_thumbMutex.lock();
pos = m_requestedThumbs.takeFirst();
m_thumbMutex.unlock();
if (thumbFolder.exists(hash() + '#' + QString::number(pos) + ".png")) {
emit thumbReady(pos, QImage(thumbFolder.absoluteFilePath(hash() + '#' + QString::number(pos) + ".png")));
continue;
}
int max = prod->get_out();
if (pos >= max) pos = max - 1;
prod->seek(pos);
Mlt::Frame *frame = prod->get_frame();
if (frame && frame->is_valid()) {
QImage img = KThumb::getFrame(frame, fullWidth, 150);
emit thumbReady(frames.at(i), img);
emit thumbReady(pos, img);
}
delete frame;
}
......
......@@ -229,7 +229,11 @@ private:
ClipType m_type;
Mlt::Producer *m_thumbsProducer;
QMutex m_producerMutex;
QMutex m_thumbMutex;
QFuture <void> m_thumbThread;
QList <int> m_requestedThumbs;
const QString geometryWithOffset(const QString &data, int offset);
void doExtractImage();
signals:
void gotAudioData();
......
......@@ -191,7 +191,7 @@ const QString ClipController::clipId()
// static
const char *ClipController::getPassPropertiesList()
{
return "kdenlive:proxy,kdenlive:originalurl,force_aspect_num,force_aspect_den,force_aspect_ratio,force_fps,force_progressive,force_tff,threads,force_colorspace,set.force_full_luma,templatetext,file_hash,xmldata";
return "kdenlive:proxy,kdenlive:originalurl,force_aspect_num,force_aspect_den,force_aspect_ratio,force_fps,force_progressive,force_tff,threads,force_colorspace,set.force_full_luma,templatetext,file_hash,xmldata,length";
}
QMap <QString, QString> ClipController::getPropertiesFromPrefix(const QString &prefix, bool withPrefix)
......
......@@ -117,9 +117,6 @@ ClipItem::~ClipItem()
blockSignals(true);
m_endThumbTimer.stop();
m_startThumbTimer.stop();
m_thumbThreads.setCancelOnWait(true);
m_thumbThreads.waitForFinished();
m_thumbThreads.clearFutures();
if (scene())
scene()->removeItem(this);
//if (m_clipType == Video | AV | SlideShow | Playlist) { // WRONG, cannot use |
......@@ -458,7 +455,7 @@ void ClipItem::slotFetchThumbs()
}
if (!frames.isEmpty()) {
m_thumbThreads.addFuture(QtConcurrent::run(m_binClip, &ProjectClip::slotExtractImage, frames));
m_binClip->slotExtractImage(frames);
}
}
......@@ -472,17 +469,13 @@ void ClipItem::stopThumbs()
void ClipItem::slotGetStartThumb()
{
m_startThumbRequested = true;
m_thumbThreads.addFuture(QtConcurrent::run(m_binClip, &ProjectClip::slotExtractImage, QList<int>() << (int)m_speedIndependantInfo.cropStart.frames(m_fps)));
//TODO
//m_clip->slotExtractImage(QList<int>() << (int)m_speedIndependantInfo.cropStart.frames(m_fps));
m_binClip->slotExtractImage(QList<int>() << (int)m_speedIndependantInfo.cropStart.frames(m_fps));
}
void ClipItem::slotGetEndThumb()
{
m_endThumbRequested = true;
m_thumbThreads.addFuture(QtConcurrent::run(m_binClip, &ProjectClip::slotExtractImage, QList<int>() << (int)(m_speedIndependantInfo.cropStart + m_speedIndependantInfo.cropDuration).frames(m_fps) - 1));
//TODO
//m_clip->slotExtractImage(QList<int>() << (int)(m_speedIndependantInfo.cropStart + m_speedIndependantInfo.cropDuration).frames(m_fps) - 1);
m_binClip->slotExtractImage(QList<int>() << (int)(m_speedIndependantInfo.cropStart + m_speedIndependantInfo.cropDuration).frames(m_fps) - 1);
}
......@@ -521,7 +514,6 @@ void ClipItem::slotThumbReady(int frame, const QImage &img)
if (m_clipType == Image || m_clipType == Text) {
update(r.right() - width, r.top(), width, pix.height());
}
clearThumbthreads();
} else if (m_endThumbRequested && frame == (m_speedIndependantInfo.cropStart + m_speedIndependantInfo.cropDuration).frames(m_fps) - 1) {
QRectF r = boundingRect();
QPixmap pix = QPixmap::fromImage(img);
......@@ -529,20 +521,6 @@ void ClipItem::slotThumbReady(int frame, const QImage &img)
m_endPix = pix;
m_endThumbRequested = false;
update(r.right() - width, r.top(), width, pix.height());
clearThumbthreads();
}
}
void ClipItem::clearThumbthreads()
{
if (!m_thumbThreads.futures().isEmpty()) {
// Remove inactive threads
QList <QFuture<void> > futures = m_thumbThreads.futures();
m_thumbThreads.clearFutures();
for (int i = 0; i < futures.count(); ++i)
if (!futures.at(i).isFinished()) {
m_thumbThreads.addFuture(futures.at(i));
}
}
}
......
......@@ -236,11 +236,9 @@ private:
QMap<int, QPixmap> m_audioThumbCachePic;
bool m_audioThumbReady;
double m_framePixelWidth;
QFutureSynchronizer<void> m_thumbThreads;
QPixmap m_videoPix;
QPixmap m_audioPix;
bool parseKeyframes(const QLocale locale, QDomElement e);
void clearThumbthreads();
private slots:
void slotGetStartThumb();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment