m_audioThumbsQueue(),
m_doc(doc),
m_generatingAudioId(),
- m_abortThumb(false)
+ m_abortThumb(false),
+ m_closing(false)
{
m_clipIdCounter = 1;
m_folderIdCounter = 1;
ClipManager::~ClipManager()
{
+ m_closing = true;
m_abortThumb = true;
m_thumbsThread.waitForFinished();
m_thumbsMutex.lock();
void ClipManager::stopThumbs(const QString &id)
{
+ if (m_requestedThumbs.isEmpty() || m_closing) return;
m_abortThumb = true;
m_thumbsThread.waitForFinished();
m_thumbsMutex.lock();
while (!values.isEmpty() && clip->thumbProducer() && !m_abortThumb) {
clip->thumbProducer()->getThumb(values.takeFirst());
}
- if (m_abortThumb) {
- // keep the requested frames that were not processed
- m_thumbsMutex.lock();
- foreach (int frame, values)
- m_requestedThumbs.insertMulti(producerId, frame);
- m_thumbsMutex.unlock();
- }
}
}
QFuture<void> m_thumbsThread;
/** @brief If true, abort processing of clip thumbs before removing a clip. */
bool m_abortThumb;
+ /** @brief We are about to delete the clip producer, stop processing thumbs. */
+ bool m_closing;
signals:
void reloadClip(const QString &);
m_audioTimer->stop();
delete m_audioTimer;
}
+ qDeleteAll(m_toDeleteProducers);
+ m_toDeleteProducers.clear();
qDeleteAll(m_baseTrackProducers);
m_baseTrackProducers.clear();
qDeleteAll(m_audioTrackProducers);
void DocClipBase::deleteProducers()
{
- m_thumbProd->clearProducer();
+ if (m_thumbProd) m_thumbProd->clearProducer();
if (numReferences() > 0) {
// Clip is used in timeline, delay producers deletion
KThumb::~KThumb()
{
- m_clipManager->stopThumbs(m_id);
+ if (m_producer) m_clipManager->stopThumbs(m_id);
m_intraFramesQueue.clear();
if (m_audioThumbProducer.isRunning()) {
m_stopAudioThumbs = true;
void KThumb::setProducer(Mlt::Producer *producer)
{
- m_clipManager->stopThumbs(m_id);
+ if (m_producer) m_clipManager->stopThumbs(m_id);
m_intraFramesQueue.clear();
m_intra.waitForFinished();
m_mutex.lock();
// FIXME: the profile() call leaks an object, but trying to free
// it leads to a double-free in Profile::~Profile()
if (producer) {
- m_dar = producer->profile()->dar();
- m_ratio = (double) producer->profile()->width() / producer->profile()->height();
+ Mlt::Profile *profile = producer->profile();
+ m_dar = profile->dar();
+ m_ratio = (double) profile->width() / profile->height();
}
m_mutex.unlock();
}
void KThumb::clearProducer()
{
- setProducer(NULL);
+ if (m_producer) setProducer(NULL);
}
bool KThumb::hasProducer() const
if (addedThumbs) emit thumbsCached();
}
-QImage KThumb::findCachedThumb(const QString path)
+QImage KThumb::findCachedThumb(const QString &path)
{
QImage img;
m_clipManager->pixmapCache->findImage(path, &img);
/** @brief Request thumbnails for the frame range. */
void queryIntraThumbs(QList <int> missingFrames);
/** @brief Query cached thumbnail. */
- QImage findCachedThumb(const QString path);
+ QImage findCachedThumb(const QString &path);
#endif
void getThumb(int frame);
closeTabButton->adjustSize();
closeTabButton->setToolTip(i18n("Close the current tab"));
m_timelineArea->setCornerWidget(closeTabButton);
- connect(m_timelineArea, SIGNAL(currentChanged(int)), this, SLOT(activateDocument()));
+ //connect(m_timelineArea, SIGNAL(currentChanged(int)), this, SLOT(activateDocument()));
connect(&m_findTimer, SIGNAL(timeout()), this, SLOT(findTimeout()));
m_findTimer.setSingleShot(true);
}
}
m_clipMonitor->slotSetClipProducer(NULL);
+ m_projectList->slotResetProjectList();
m_timelineArea->removeTab(m_timelineArea->indexOf(w));
if (m_timelineArea->count() == 1) {
m_timelineArea->setTabBarHidden(true);
bool ok;
TrackView *trackView = new TrackView(doc, &ok, this);
-
+ connectDocument(trackView, doc);
progressDialog.progressBar()->setValue(3);
qApp->processEvents();
QTreeWidgetItemIterator it(m_listView);
ProjectItem *item;
- while (*it) {
+ while (*it && !m_abortAllProxies) {
if ((*it)->type() == PROJECTCLIPTYPE) {
item = static_cast <ProjectItem *>(*it);
if (item->referencedClip()->getProperty("proxy") == proxyPath)
void ProjectList::slotResetProjectList()
{
+ m_listView->blockSignals(true);
m_abortAllProxies = true;
m_proxyThreads.waitForFinished();
m_proxyThreads.clearFutures();
m_refreshed = false;
m_allClipsProcessed = false;
m_abortAllProxies = false;
+ m_listView->blockSignals(false);
}
void ProjectList::slotUpdateClip(const QString &id)
// Proxy process crashed
QFile::remove(info.dest);
setProxyStatus(info.dest, PROXYCRASHED);
- }
-
+ }
+ return;
}
if (info.type == IMAGE) {
m_abortProxy.removeAll(info.dest);
m_processingProxy.removeAll(info.dest);
QFile::remove(info.dest);
- setProxyStatus(info.dest, NOPROXY);
+ if (!m_abortAllProxies) setProxyStatus(info.dest, NOPROXY);
result = -2;
}
if (proxyPath.isEmpty() || m_abortAllProxies) return;
QTreeWidgetItemIterator it(m_listView);
ProjectItem *item;
- while (*it) {
+ while (*it && !m_abortAllProxies) {
if ((*it)->type() == PROJECTCLIPTYPE) {
item = static_cast <ProjectItem *>(*it);
if (item->referencedClip()->getProperty("proxy") == proxyPath) {