X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectlist.cpp;h=fdba31b31a92af0057b012242acd16669060d90a;hb=eb74feb585496fc8e7349a348a6d1222a6d1792a;hp=a00d6f4043b48da3f6a04a76450db430e5a2bf65;hpb=6c819d9cd57a199efc99ec3f6a4a54eae9a232c0;p=kdenlive diff --git a/src/projectlist.cpp b/src/projectlist.cpp index a00d6f40..fdba31b3 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -227,7 +227,7 @@ ProjectList::ProjectList(QWidget *parent) : m_reloadAction(NULL), m_extractAudioAction(NULL), m_transcodeAction(NULL), - m_stabilizeAction(NULL), + m_clipsActionsMenu(NULL), m_doc(NULL), m_refreshed(false), m_allClipsProcessed(false), @@ -431,7 +431,7 @@ void ProjectList::setupGeneratorMenu(const QHash& menus) m_menu->addMenu(stabilizeMenu); if (stabilizeMenu->isEmpty()) stabilizeMenu->setEnabled(false); - m_stabilizeAction=stabilizeMenu; + m_clipsActionsMenu = stabilizeMenu; } m_menu->addAction(m_reloadAction); @@ -715,10 +715,11 @@ void ProjectList::slotReloadClip(const QString &id) QDomElement e = item->toXml(); // Make sure we get the correct producer length if it was adjusted in timeline if (t == COLOR || t == IMAGE || t == SLIDESHOW || t == TEXT) { - int length = QString(clip->producerProperty("length")).toInt(); - if (length > 0 && !e.hasAttribute("length")) { - e.setAttribute("length", length); - } + int length = QString(clip->producerProperty("length")).toInt(); + if (length > 0 && !e.hasAttribute("length")) { + e.setAttribute("length", length); + } + e.setAttribute("duration", clip->getProperty("duration")); } resetThumbsProducer(clip); m_render->getFileProperties(e, item->clipId(), m_listView->iconSize().height(), true); @@ -834,7 +835,7 @@ void ProjectList::slotClipSelected() m_reloadAction->setEnabled(false); m_extractAudioAction->setEnabled(false); m_transcodeAction->setEnabled(false); - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); } else { if (item->type() == PROJECTSUBCLIPTYPE) { // this is a sub item, use base clip @@ -842,10 +843,11 @@ void ProjectList::slotClipSelected() clip = static_cast (item->parent()); if (clip == NULL) kDebug() << "-----------ERROR"; SubProjectItem *sub = static_cast (item); + if (clip->referencedClip()->getProducer() == NULL) m_render->getFileProperties(clip->referencedClip()->toXML(), clip->clipId(), m_listView->iconSize().height(), true); emit clipSelected(clip->referencedClip(), sub->zone()); m_extractAudioAction->setEnabled(false); m_transcodeAction->setEnabled(false); - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); m_reloadAction->setEnabled(false); adjustProxyActions(clip); return; @@ -853,12 +855,13 @@ void ProjectList::slotClipSelected() clip = static_cast (item); if (clip && clip->referencedClip()) emit clipSelected(clip->referencedClip()); + if (clip->referencedClip()->getProducer() == NULL) m_render->getFileProperties(clip->referencedClip()->toXML(), clip->clipId(), m_listView->iconSize().height(), true); m_editButton->defaultAction()->setEnabled(true); m_deleteButton->defaultAction()->setEnabled(true); m_reloadAction->setEnabled(true); m_extractAudioAction->setEnabled(true); m_transcodeAction->setEnabled(true); - m_stabilizeAction->setEnabled(true); + m_clipsActionsMenu->setEnabled(true); if (clip && clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) { m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp())); m_openAction->setEnabled(true); @@ -882,7 +885,7 @@ void ProjectList::slotClipSelected() m_reloadAction->setEnabled(false); m_extractAudioAction->setEnabled(true); m_transcodeAction->setEnabled(false); - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); } adjustProxyActions(clip); } @@ -905,10 +908,10 @@ void ProjectList::adjustStabilizeActions(ProjectItem *clip) const { if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == SLIDESHOW) { - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); return; } - m_stabilizeAction->setEnabled(true); + m_clipsActionsMenu->setEnabled(true); } @@ -948,13 +951,12 @@ void ProjectList::slotUpdateClipProperties(const QString &id, QMap setEnabled(enable); m_extractAudioAction->setEnabled(enable); m_transcodeAction->setEnabled(enable); - m_stabilizeAction->setEnabled(enable); + m_clipsActionsMenu->setEnabled(enable); if (enable) { ProjectItem *clip = NULL; if (m_listView->currentItem()->type() == PROJECTSUBCLIPTYPE) { clip = static_cast (item->parent()); m_extractAudioAction->setEnabled(false); m_transcodeAction->setEnabled(false); - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); adjustProxyActions(clip); } else if (m_listView->currentItem()->type() == PROJECTCLIPTYPE) { clip = static_cast (item); @@ -1094,7 +1096,7 @@ void ProjectList::slotContextMenu(const QPoint &pos, QTreeWidgetItem *item) } else { m_extractAudioAction->setEnabled(false); m_transcodeAction->setEnabled(false); - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); } if (clip && clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) { m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp())); @@ -1172,7 +1174,7 @@ void ProjectList::updateButtons() const m_openAction->setEnabled(true); m_reloadAction->setEnabled(true); m_transcodeAction->setEnabled(true); - m_stabilizeAction->setEnabled(true); + m_clipsActionsMenu->setEnabled(true); return; } else if (item && item->type() == PROJECTFOLDERTYPE && item->childCount() > 0) { @@ -1183,7 +1185,7 @@ void ProjectList::updateButtons() const m_openAction->setEnabled(false); m_reloadAction->setEnabled(false); m_transcodeAction->setEnabled(false); - m_stabilizeAction->setEnabled(false); + m_clipsActionsMenu->setEnabled(false); m_proxyAction->setEnabled(false); } @@ -1458,7 +1460,9 @@ void ProjectList::getCachedThumbnail(ProjectItem *item) { if (!item) return; DocClipBase *clip = item->referencedClip(); - if (!clip) return; + if (!clip) { + return; + } QString cachedPixmap = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "thumbs/" + clip->getClipHash() + ".png"; if (QFile::exists(cachedPixmap)) { QPixmap pix(cachedPixmap); @@ -1578,6 +1582,7 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged, QStr } if (clip->isPlaceHolder() == false && !hasPendingJob(item, PROXYJOB)) { QDomElement xml = clip->toXML(); + getCachedThumbnail(item); if (fpsChanged) { xml.removeAttribute("out"); xml.removeAttribute("file_hash"); @@ -1587,8 +1592,12 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged, QStr xml.removeAttribute("_replaceproxy"); if (replace) { resetThumbsProducer(clip); + m_render->getFileProperties(xml, clip->getId(), m_listView->iconSize().height(), replace); } - m_render->getFileProperties(xml, clip->getId(), m_listView->iconSize().height(), replace); + else if (item->numReferences() > 0) { + // In some cases, like slowmotion clips, the producer is not loaded automatically be MLT + m_render->getFileProperties(xml, clip->getId(), m_listView->iconSize().height(), replace); + } } else if (clip->isPlaceHolder()) { item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); @@ -2191,7 +2200,6 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce { QString toReload; ProjectItem *item = getItemById(clipId); - int queue = m_render->processingItems(); if (item && producer) { monitorItemEditing(false); DocClipBase *clip = item->referencedClip(); @@ -2204,6 +2212,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce } item->setProperties(properties, metadata); clip->setProducer(producer, replace); + m_render->processingDone(clipId); // Proxy stuff QString size = properties.value("frame_size"); @@ -2243,7 +2252,11 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce } if (!toReload.isEmpty()) item->slotSetToolTip(); - } else kDebug() << "//////// COULD NOT FIND CLIP TO UPDATE PRPS..."; + } else { + kDebug() << "//////// COULD NOT FIND CLIP TO UPDATE PRPS..."; + m_render->processingDone(clipId); + } + int queue = m_render->processingItems(); if (queue == 0) { monitorItemEditing(true); if (item && m_thumbnailQueue.isEmpty()) { @@ -2475,7 +2488,7 @@ void ProjectList::slotSelectClip(const QString &ix) m_reloadAction->setEnabled(true); m_extractAudioAction->setEnabled(true); m_transcodeAction->setEnabled(true); - m_stabilizeAction->setEnabled(true); + m_clipsActionsMenu->setEnabled(true); if (clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) { m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp())); m_openAction->setEnabled(true); @@ -2944,22 +2957,21 @@ void ProjectList::slotCheckJobProcess() } } if (m_jobList.isEmpty()) return; - int count = 0; + m_jobMutex.lock(); + int count = 0; for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->jobStatus == JOBWORKING || m_jobList.at(i)->jobStatus == JOBWAITING) + if (m_jobList.at(i)->status() == JOBWORKING || m_jobList.at(i)->status() == JOBWAITING) count ++; else { // remove finished jobs AbstractClipJob *job = m_jobList.takeAt(i); - delete job; + job->deleteLater(); i--; } } - - emit jobCount(count); + emit jobCount(count); m_jobMutex.unlock(); - if (m_jobThreads.futures().isEmpty() || m_jobThreads.futures().count() < KdenliveSettings::proxythreads()) m_jobThreads.addFuture(QtConcurrent::run(this, &ProjectList::slotProcessJobs)); } @@ -2982,14 +2994,14 @@ void ProjectList::slotProcessJobs() int count = 0; m_jobMutex.lock(); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->jobStatus == JOBWAITING) { + if (m_jobList.at(i)->status() == JOBWAITING) { if (job == NULL) { - m_jobList.at(i)->jobStatus = JOBWORKING; + m_jobList.at(i)->setStatus(JOBWORKING); job = m_jobList.at(i); } count++; } - else if (m_jobList.at(i)->jobStatus == JOBWORKING) + else if (m_jobList.at(i)->status() == JOBWORKING) count ++; } // Set jobs count @@ -3028,20 +3040,20 @@ void ProjectList::slotProcessJobs() MeltJob *jb = static_cast (job); jb->setProducer(currentClip->getProducer(), currentClip->fileURL()); if (jb->isProjectFilter()) - connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SLOT(slotGotFilterJobResults(QString,int, int,stringMap,stringMap))); + connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SLOT(slotGotFilterJobResults(QString,int, int,stringMap,stringMap))); else connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SIGNAL(gotFilterJobResults(QString,int, int,stringMap,stringMap))); } job->startJob(); - if (job->jobStatus == JOBDONE) { + if (job->status() == JOBDONE) { emit updateJobStatus(job->clipId(), job->jobType, JOBDONE); //TODO: replace with more generic clip replacement framework if (job->jobType == PROXYJOB) emit gotProxy(job->clipId()); if (job->addClipToProject()) { emit addClip(destination, QString(), QString()); } - } else if (job->jobStatus == JOBCRASHED || job->jobStatus == JOBABORTED) { - emit updateJobStatus(job->clipId(), job->jobType, job->jobStatus, job->errorMessage(), QString(), job->logDetails()); + } else if (job->status() == JOBCRASHED || job->status() == JOBABORTED) { + emit updateJobStatus(job->clipId(), job->jobType, job->status(), job->errorMessage(), QString(), job->logDetails()); } } // Thread finished, cleanup & update count @@ -3345,7 +3357,7 @@ bool ProjectList::hasPendingJob(ProjectItem *item, JOBTYPE type) for (int i = 0; i < m_jobList.count(); i++) { if (m_abortAllJobs) break; job = m_jobList.at(i); - if (job->clipId() == item->clipId() && job->jobType == type && (job->jobStatus == JOBWAITING || job->jobStatus == JOBWORKING)) return true; + if (job->clipId() == item->clipId() && job->jobType == type && (job->status() == JOBWAITING || job->status() == JOBWORKING)) return true; } return false; @@ -3437,7 +3449,7 @@ QStringList ProjectList::getPendingJobs(const QString &id) QStringList result; QMutexLocker lock(&m_jobMutex); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->jobStatus == JOBWAITING || m_jobList.at(i)->jobStatus == JOBWORKING)) { + if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->status() == JOBWAITING || m_jobList.at(i)->status() == JOBWORKING)) { // discard this job result << m_jobList.at(i)->description; } @@ -3508,14 +3520,16 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c // Producer params jobParams << QString(); // Filter params, use a smaller region of the image to speed up operation - jobParams << filterName << "bounding=\"25%x25%:15%x15\" shot_change_list=0 denoise=0"; + // In fact, it's faster to rescale whole image than using part of it (bounding=\"25%x25%:15%x15\") + jobParams << filterName << "shot_change_list=0 denoise=0"; // Consumer - jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1"; + jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1 rescale=nearest deinterlace_method=onefield top_field_first=-1"; QMap extraParams; extraParams.insert("key", "shot_change_list"); extraParams.insert("projecttreefilter", "1"); QString keyword("%count"); extraParams.insert("resultmessage", i18n("Found %1 scenes.", keyword)); + extraParams.insert("resize_profile", "160"); if (ui.store_data->isChecked()) { // We want to save result as clip metadata extraParams.insert("storedata", "1"); @@ -3594,9 +3608,10 @@ void ProjectList::processClipJob(QStringList ids, const QString&destination, boo job->description = description; m_jobList.append(job); setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage()); + slotCheckJobProcess(); } - slotCheckJobProcess(); } + void ProjectList::slotPrepareJobsMenu() { @@ -3650,9 +3665,10 @@ void ProjectList::slotClosePopup() void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap results, stringMap filterInfo) { // Currently, only the first value of results is used - kDebug()<<"// FILTER RES:\n"<