aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <[email protected]>2015-01-09 15:43:37 +0100
committerJean-Baptiste Mardelle <[email protected]>2015-01-09 15:43:37 +0100
commit4815a1e4dd2993160e61d16d2dad41feb654a97d (patch)
tree2d3b73c7a4487a4742a48c4f2ec593cfb391b190
parent44c0df9ff57c15e362c1bff15e3829957e773c6c (diff)
Cleanup clip jobs
-rw-r--r--src/mainwindow.cpp31
-rw-r--r--src/mainwindow.h1
-rw-r--r--src/project/CMakeLists.txt6
-rw-r--r--src/project/jobs/CMakeLists.txt9
-rw-r--r--src/project/jobs/abstractclipjob.h5
-rw-r--r--src/project/jobs/filterjob.cpp237
-rw-r--r--src/project/jobs/filterjob.h40
-rw-r--r--src/project/jobs/jobmanager.cpp228
-rw-r--r--src/project/jobs/jobmanager.h3
-rw-r--r--src/project/jobs/meltjob.cpp50
-rw-r--r--src/project/jobs/meltjob.h1
-rw-r--r--src/project/projectlist.cpp203
-rw-r--r--src/project/projectlist.h4
13 files changed, 329 insertions, 489 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index ee4226e..618bcae 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -2650,8 +2650,10 @@ void MainWindow::loadClipActions()
else {
delete filter;
QAction *action=actionMenu->addAction(i18n("Stabilize"));
- action->setData("vidstab");
- connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+ QStringList stabJob;
+ stabJob << QString::number((int) AbstractClipJob::FILTERCLIPJOB) << "vidstab";
+ action->setData(stabJob);
+ connect(action, SIGNAL(triggered(bool)), pCore->bin(), SLOT(slotStartClipJob(bool)));
}
}
filter = Mlt::Factory::filter(profile,(char*)"motion_est");
@@ -2662,14 +2664,18 @@ void MainWindow::loadClipActions()
else {
delete filter;
QAction *action=actionMenu->addAction(i18n("Automatic scene split"));
- action->setData("motion_est");
- connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+ QStringList stabJob;
+ stabJob << QString::number((int) AbstractClipJob::FILTERCLIPJOB) << "motion_est";
+ action->setData(stabJob);
+ connect(action, SIGNAL(triggered(bool)), pCore->bin(), SLOT(slotStartClipJob(bool)));
}
}
if (KdenliveSettings::producerslist().contains("framebuffer")) {
QAction *action=actionMenu->addAction(i18n("Reverse clip"));
- action->setData("framebuffer");
- connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+ QStringList stabJob;
+ stabJob << QString::number((int) AbstractClipJob::FILTERCLIPJOB) << "framebuffer";
+ action->setData(stabJob);
+ connect(action, SIGNAL(triggered(bool)), pCore->bin(), SLOT(slotStartClipJob(bool)));
}
}
@@ -2708,19 +2714,6 @@ void MainWindow::loadTranscoders()
}
}
-void MainWindow::slotStartClipAction()
-{
- QString condition,filtername;
- QStringList ids;
-
- // Stablize selected clips
- QAction *action = qobject_cast<QAction *>(sender());
- if (action){
- filtername=action->data().toString();
- }
- m_projectList->startClipFilterJob(filtername, condition);
-}
-
void MainWindow::slotTranscode(const QStringList &urls)
{
QString params;
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 0b16697..4ffa1ec 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -394,7 +394,6 @@ private slots:
void slotUpdateClipType(QAction *action);
void slotShowTimeline(bool show);
void slotTranscode(const QStringList &urls = QStringList());
- void slotStartClipAction();
void slotTranscodeClip();
/** @brief Archive project: creates a copy of the project file with all clips in a new folder. */
void slotArchiveProject();
diff --git a/src/project/CMakeLists.txt b/src/project/CMakeLists.txt
index 0960adf..99a1470 100644
--- a/src/project/CMakeLists.txt
+++ b/src/project/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(dialogs)
+add_subdirectory(jobs)
set(kdenlive_SRCS
${kdenlive_SRCS}
project/clipmanager.cpp
@@ -16,9 +17,4 @@ set(kdenlive_SRCS
project/subprojectitem.cpp
project/transitionsettings.cpp
project/notesplugin.cpp
- project/jobs/abstractclipjob.cpp
- project/jobs/proxyclipjob.cpp
- project/jobs/cutclipjob.cpp
- project/jobs/meltjob.cpp
- project/jobs/jobmanager.cpp
PARENT_SCOPE)
diff --git a/src/project/jobs/CMakeLists.txt b/src/project/jobs/CMakeLists.txt
new file mode 100644
index 0000000..23fe93a
--- /dev/null
+++ b/src/project/jobs/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(kdenlive_SRCS
+ ${kdenlive_SRCS}
+ project/jobs/abstractclipjob.cpp
+ project/jobs/proxyclipjob.cpp
+ project/jobs/cutclipjob.cpp
+ project/jobs/meltjob.cpp
+ project/jobs/filterjob.cpp
+ project/jobs/jobmanager.cpp
+ PARENT_SCOPE)
diff --git a/src/project/jobs/abstractclipjob.h b/src/project/jobs/abstractclipjob.h
index a1555d5..2012490 100644
--- a/src/project/jobs/abstractclipjob.h
+++ b/src/project/jobs/abstractclipjob.h
@@ -32,8 +32,9 @@ class AbstractClipJob : public QObject
Q_OBJECT
public:
- enum JOBTYPE { NOJOBTYPE = 0, PROXYJOB = 1, CUTJOB = 2, MLTJOB = 3, TRANSCODEJOB = 4};
- AbstractClipJob(JOBTYPE type, ClipType cType, const QString &id); virtual ~ AbstractClipJob();
+ enum JOBTYPE { NOJOBTYPE = 0, PROXYJOB = 1, CUTJOB = 2, MLTJOB = 3, TRANSCODEJOB = 4, FILTERCLIPJOB = 5 };
+ AbstractClipJob(JOBTYPE type, ClipType cType, const QString &id);
+ virtual ~ AbstractClipJob();
ClipType clipType;
JOBTYPE jobType;
QString description;
diff --git a/src/project/jobs/filterjob.cpp b/src/project/jobs/filterjob.cpp
new file mode 100644
index 0000000..c2d7228
--- /dev/null
+++ b/src/project/jobs/filterjob.cpp
@@ -0,0 +1,237 @@
+/***************************************************************************
+ * *
+ * Copyright (C) 2015 by Jean-Baptiste Mardelle ([email protected]) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "filterjob.h"
+#include "meltjob.h"
+#include "kdenlivesettings.h"
+#include "doc/kdenlivedoc.h"
+#include "bin/projectclip.h"
+#include "project/clipstabilize.h"
+#include "ui_scenecutdialog_ui.h"
+
+#include <QDebug>
+#include <QUrl>
+#include <klocalizedstring.h>
+
+#include <mlt++/Mlt.h>
+
+// static
+QList <ProjectClip *> FilterJob::filterClips(QList <ProjectClip *>clips, const QStringList &params)
+{
+ QString condition;
+ if (params.count() > 3) {
+ // there is a condition for this job, for example operate only on vcodec=mpeg1video
+ condition = params.at(3);
+ }
+ QList <ProjectClip *> result;
+ for (int i = 0; i < clips.count(); i++) {
+ ProjectClip *clip = clips.at(i);
+ ClipType type = clip->clipType();
+ if (type != AV && type != Audio && type != Video) {
+ // Clip will not be processed by this job
+ continue;
+ }
+ if (!condition.isEmpty() && !clip->matches(condition)) {
+ // Clip does not match requested condition, do not process
+ continue;
+ }
+ result << clip;
+ }
+ return result;
+}
+
+QMap <ProjectClip *, AbstractClipJob *> FilterJob::prepareJob(double fps, QList <ProjectClip*> clips, QStringList parameters)
+{
+ QMap <ProjectClip *, AbstractClipJob *> jobs;
+ QStringList sources;
+ for (int i = 0; i < clips.count(); i++) {
+ sources << clips.at(i)->url().toLocalFile();
+ }
+ QString filterName = parameters.first();
+ if (filterName == "framebuffer") {
+ Mlt::Profile profile;
+ QMap <QString, QString> producerParams = QMap <QString, QString> ();
+ QMap <QString, QString> filterParams = QMap <QString, QString> ();
+ QMap <QString, QString> consumerParams = QMap <QString, QString> ();
+ QMap <QString, QString> extraParams = QMap <QString, QString> ();
+ producerParams.insert("in", "0");
+ producerParams.insert("out", "-1");
+ extraParams.insert("projecttreefilter", "1");
+ extraParams.insert("producer_profile", "1");
+ for (int i = 0; i < clips.count(); i++) {
+ QString prodstring = QString("framebuffer:" + sources.at(i) + "?-1");
+ producerParams.insert("producer", prodstring);
+ consumerParams.insert("consumer", "xml:" + sources.at(i) + ".mlt");
+ ProjectClip *clip = clips.at(i);
+ MeltJob *job = new MeltJob(clip->clipType(), clip->clipId(), producerParams, filterParams, consumerParams, extraParams);
+ job->description = i18n("Reverse clip");
+ job->setAddClipToProject(true);
+ jobs.insert(clip, job);
+ }
+ return jobs;
+ }
+ if (filterName == "motion_est") {
+ // Show config dialog
+ QPointer<QDialog> d = new QDialog(QApplication::activeWindow());
+ Ui::SceneCutDialog_UI ui;
+ ui.setupUi(d);
+ // Set up categories
+ for (int i = 0; i < 5; ++i) {
+ ui.marker_type->insertItem(i, i18n("Category %1", i));
+ ui.marker_type->setItemData(i, CommentedTime::markerColor(i), Qt::DecorationRole);
+ }
+ ui.marker_type->setCurrentIndex(KdenliveSettings::default_marker_type());
+ if (d->exec() != QDialog::Accepted) {
+ delete d;
+ return jobs;
+ }
+ // Autosplit filter
+ QMap <QString, QString> producerParams = QMap <QString, QString> ();
+ QMap <QString, QString> filterParams = QMap <QString, QString> ();
+ QMap <QString, QString> consumerParams = QMap <QString, QString> ();
+
+ // Producer params
+ // None
+
+ // Filter params, use a smaller region of the image to speed up operation
+ // In fact, it's faster to rescale whole image than using part of it (bounding=\"25%x25%:15%x15\")
+ filterParams.insert("filter", filterName);
+ filterParams.insert("shot_change_list", "0");
+ filterParams.insert("denoise", "0");
+
+ // Consumer
+ consumerParams.insert("consumer", "null");
+ consumerParams.insert("all", "1");
+ consumerParams.insert("terminate_on_pause", "1");
+ consumerParams.insert("real_time", "-1");
+ // We just want to find scene change, set all mathods to the fastests
+ consumerParams.insert("rescale", "nearest");
+ consumerParams.insert("deinterlace_method", "onefield");
+ consumerParams.insert("top_field_first", "-1");
+
+ // Extra
+ QMap <QString, QString> 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");
+ }
+ if (ui.zone_only->isChecked()) {
+ // We want to analyze only clip zone
+ extraParams.insert("zoneonly", "1");
+ }
+ if (ui.add_markers->isChecked()) {
+ // We want to create markers
+ extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex()));
+ }
+ if (ui.cut_scenes->isChecked()) {
+ // We want to cut scenes
+ extraParams.insert("cutscenes", "1");
+ }
+ delete d;
+
+ for (int i = 0; i < clips.count(); i++) {
+ // Set clip specific infos
+
+ // in and out
+ int in = 0;
+ int out = -1;
+ ProjectClip *clip = clips.at(i);
+ if (extraParams.contains("zoneonly")) {
+ // Analyse clip zone only, remove in / out and replace with zone
+ QPoint zone = clip->zone();
+ in = zone.x();
+ out = zone.y();
+ }
+ producerParams.insert("in", QString::number(in));
+ producerParams.insert("out", QString::number(out));
+ producerParams.insert("producer", sources.at(i));
+
+ // Destination
+ // Since this job is only doing analysis, we have a null consumer and no destination
+ MeltJob *job = new MeltJob(clip->clipType(), clip->clipId(), producerParams, filterParams, consumerParams, extraParams);
+ job->description = i18n("Auto split");
+ jobs.insert(clip, job);
+ }
+ return jobs;
+ }
+ if (filterName == "vidstab") {
+ // vidstab
+ QPointer<ClipStabilize> d = new ClipStabilize(sources, filterName);
+ if (d->exec() == QDialog::Accepted) {
+ QMap <QString, QString> producerParams = d->producerParams();
+ QMap <QString, QString> filterParams = d->filterParams();
+ QMap <QString, QString> consumerParams = d->consumerParams();
+ QMap <QString, QString> extraParams;
+ extraParams.insert("producer_profile", "1");
+ QString destination = d->destination();
+ QUrl trffile;
+ for (int i = 0; i < clips.count(); i++) {
+ // Set clip specific infos
+
+ // in and out
+ int in = 0;
+ int out = -1;
+ ProjectClip *clip = clips.at(i);
+ if (extraParams.contains("zoneonly")) {
+ // Analyse clip zone only, remove in / out and replace with zone
+ QPoint zone = clip->zone();
+ in = zone.x();
+ out = zone.y();
+ }
+ producerParams.insert("in", QString::number(in));
+ producerParams.insert("out", QString::number(out));
+ producerParams.insert("producer", sources.at(i));
+
+ // Consumer
+ QString consumerName = consumerParams.value("consumer");
+ if (clips.count() == 1) {
+ // We only have one clip, destination points to the final url
+ consumerParams.insert("consumer", consumerName + ':' + destination);
+ trffile = QUrl::fromLocalFile(destination + ".trf");
+ } else {
+ // Filter several clips, destination points to a folder
+ QString mltfile = destination + clip->url().fileName() + ".mlt";
+ consumerParams.insert("consumer", consumerName + ':' + mltfile);
+ trffile = QUrl::fromLocalFile(mltfile + ".trf");
+ }
+ // Append a 'filename' parameter for saving vidstab data
+ filterParams.insert("filename", trffile.path());
+ MeltJob *job = new MeltJob(clip->clipType(), clip->clipId(), producerParams, filterParams, consumerParams, extraParams);
+ job->setAddClipToProject(d->autoAddClip());
+ job->description = d->desc();
+ jobs.insert(clip, job);
+ }
+ }
+ delete d;
+ return jobs;
+ }
+ return jobs;
+}
+
+
+
+
+
+
diff --git a/src/project/jobs/filterjob.h b/src/project/jobs/filterjob.h
new file mode 100644
index 0000000..d4bdd19
--- /dev/null
+++ b/src/project/jobs/filterjob.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * *
+ * Copyright (C) 2015 by Jean-Baptiste Mardelle ([email protected]) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef FILTERJOB
+#define FILTERJOB
+
+#include <QList>
+#include <QMap>
+#include <QStringList>
+
+class QUrl;
+class ProjectClip;
+class AbstractClipJob;
+
+class FilterJob
+{
+
+public:
+ static QList <ProjectClip *> filterClips(QList <ProjectClip *>clips, const QStringList &params);
+ static QMap <ProjectClip *, AbstractClipJob *> prepareJob(double fps, QList <ProjectClip*> clips, QStringList parameters);
+};
+
+#endif
diff --git a/src/project/jobs/jobmanager.cpp b/src/project/jobs/jobmanager.cpp
index e7d1c22..9a71019 100644
--- a/src/project/jobs/jobmanager.cpp
+++ b/src/project/jobs/jobmanager.cpp
@@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "bin/projectclip.h"
#include "project/clipstabilize.h"
#include "meltjob.h"
+#include "filterjob.h"
#include "bin/bin.h"
#include "mlt++/Mlt.h"
@@ -91,225 +92,6 @@ void JobManager::discardJobs(const QString &id, AbstractClipJob::JOBTYPE type)
}
}
-void JobManager::slotStartFilterJob(const ItemInfo &info, const QString&id, QMap <QString, QString> &filterParams, QMap <QString, QString> &consumerParams, QMap <QString, QString> &extraParams)
-{
- ProjectClip *item = m_bin->getBinClip(id);
- if (!item) return;
-
- QMap <QString, QString> producerParams = QMap <QString, QString> ();
- producerParams.insert("in", QString::number((int) info.cropStart.frames(m_fps)));
- producerParams.insert("out", QString::number((int) (info.cropStart + info.cropDuration).frames(m_fps)));
- extraParams.insert("clipStartPos", QString::number((int) info.startPos.frames(m_fps)));
- extraParams.insert("clipTrack", QString::number(info.track));
-
- MeltJob *job = new MeltJob(item->clipType(), id, producerParams, filterParams, consumerParams, extraParams);
- if (job->isExclusive() && hasPendingJob(id, job->jobType)) {
- delete job;
- return;
- }
- job->description = i18n("Filter %1", extraParams.value("finalfilter"));
- m_jobList.append(job);
- item->setJobStatus(job->jobType, JobWaiting, 0, job->statusMessage());
- slotCheckJobProcess();
-}
-
-void JobManager::startClipFilterJob(QList <ProjectClip *> clipList, const QString &filterName)
-{
- QStringList destination;
- QStringList ids;
- for (int i = 0; i < clipList.count(); i++) {
- ProjectClip *item = clipList.at(i);
- if (!item) {
- emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2, ErrorMessage);
- continue;
- }
- else {
- ids << item->clipId();
- destination << item->url().toLocalFile();
- }
- }
- if (filterName == "framebuffer") {
- Mlt::Profile profile;
- int ix = 0;
- foreach(const QString &url, destination) {
- QString prodstring = QString("framebuffer:" + url + "?-1");
- Mlt::Producer *reversed = new Mlt::Producer(profile, prodstring.toUtf8().constData());
- if (!reversed || !reversed->is_valid()) {
- emit displayMessage(i18n("Cannot reverse clip"), -2, ErrorMessage);
- continue;
- }
- QString dest = url + ".mlt";
- if (QFile::exists(dest)) {
- if (KMessageBox::questionYesNo(QApplication::activeWindow(), i18n("File %1 already exists.\nDo you want to overwrite it?", dest)) == KMessageBox::No) continue;
- }
- Mlt::Consumer *cons = new Mlt::Consumer(profile, "xml", dest.toUtf8().constData());
- if (cons == NULL || !cons->is_valid()) {
- emit displayMessage(i18n("Cannot render reversed clip"), -2, ErrorMessage);
- continue;
- }
- Mlt::Playlist list;
- list.insert_at(0, reversed, 0);
- delete reversed;
- cons->connect(list);
- cons->run();
- delete cons;
- QString groupId;
- QString groupName;
- //TODO: get clip folder
- /*if (base) {
- groupId = base->getProperty("groupid");
- groupName = base->getProperty("groupname");
- }*/
- emit addClip(dest, groupId, groupName);
- ix++;
- }
- return;
- }
-
- if (filterName == "motion_est") {
- // Show config dialog
- QPointer<QDialog> d = new QDialog(QApplication::activeWindow());
- Ui::SceneCutDialog_UI ui;
- ui.setupUi(d);
- // Set up categories
- for (int i = 0; i < 5; ++i) {
- ui.marker_type->insertItem(i, i18n("Category %1", i));
- ui.marker_type->setItemData(i, CommentedTime::markerColor(i), Qt::DecorationRole);
- }
- ui.marker_type->setCurrentIndex(KdenliveSettings::default_marker_type());
- if (d->exec() != QDialog::Accepted) {
- delete d;
- return;
- }
- // Autosplit filter
- QMap <QString, QString> producerParams = QMap <QString, QString> ();
- QMap <QString, QString> filterParams = QMap <QString, QString> ();
- QMap <QString, QString> consumerParams = QMap <QString, QString> ();
-
- // Producer params
- // None
-
- // Filter params, use a smaller region of the image to speed up operation
- // In fact, it's faster to rescale whole image than using part of it (bounding=\"25%x25%:15%x15\")
- filterParams.insert("filter", filterName);
- filterParams.insert("shot_change_list", "0");
- filterParams.insert("denoise", "0");
-
- // Consumer
- consumerParams.insert("consumer", "null");
- consumerParams.insert("all", "1");
- consumerParams.insert("terminate_on_pause", "1");
- consumerParams.insert("real_time", "-1");
- // We just want to find scene change, set all mathods to the fastests
- consumerParams.insert("rescale", "nearest");
- consumerParams.insert("deinterlace_method", "onefield");
- consumerParams.insert("top_field_first", "-1");
-
- // Extra
- QMap <QString, QString> 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");
- }
- if (ui.zone_only->isChecked()) {
- // We want to analyze only clip zone
- extraParams.insert("zoneonly", "1");
- }
- if (ui.add_markers->isChecked()) {
- // We want to create markers
- extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex()));
- }
- if (ui.cut_scenes->isChecked()) {
- // We want to cut scenes
- extraParams.insert("cutscenes", "1");
- }
- delete d;
- processClipJob(ids, QString(), false, producerParams, filterParams, consumerParams, i18n("Auto split"), extraParams);
- }
- else {
- QPointer<ClipStabilize> d = new ClipStabilize(destination, filterName);
- if (d->exec() == QDialog::Accepted) {
- QMap <QString, QString> extraParams;
- extraParams.insert("producer_profile", "1");
- processClipJob(ids, d->destination(), d->autoAddClip(), d->producerParams(), d->filterParams(), d->consumerParams(), d->desc(), extraParams);
- }
- delete d;
- }
-}
-
-void JobManager::processClipJob(QStringList ids, const QString&destination, bool autoAdd, QMap <QString, QString> producerParams, QMap <QString, QString> filterParams, QMap <QString, QString> consumerParams, const QString &description, QMap <QString, QString> extraParams)
-{
- // in and out
- int in = 0;
- int out = -1;
-
- // filter name
- QString filterName = filterParams.value("filter");
-
- // consumer name
- QString consumerName = consumerParams.value("consumer");
-
- foreach(const QString&id, ids) {
- ProjectClip *item = m_bin->getBinClip(id);
- if (!item) continue;
- //TODO manage bin clip zones
- /*
- if (extraParams.contains("zoneonly")) {
- // Analyse clip zone only, remove in / out and replace with zone
- QPoint zone = item->zone();
- in = zone.x();
- out = zone.y();
- }*/
- producerParams.insert("in", QString::number(in));
- producerParams.insert("out", QString::number(out));
-
- if (ids.count() == 1) {
- // We only have one clip to process
- if (filterName == "vidstab") {
- // Append a 'filename' parameter for saving vidstab data
- QUrl trffile = QUrl::fromLocalFile(destination + ".trf");
- filterParams.insert("filename", trffile.path());
- consumerParams.insert("consumer", consumerName + ':' + destination);
- } else {
- consumerParams.insert("consumer", consumerName + ':' + destination);
- }
- }
- else {
- // We have several clips to process
- QString mltfile = destination + item->url().fileName() + ".mlt";
- if (filterName == "vidstab") {
- // Append a 'filename' parameter for saving each vidstab data
- QUrl trffile = QUrl::fromLocalFile(mltfile + ".trf");
- filterParams.insert("filename", trffile.path());
- consumerParams.insert("consumer", consumerName + ':' + mltfile);
- } else {
- consumerParams.insert("consumer", consumerName + ':' + mltfile);
- }
- }
- MeltJob *job = new MeltJob(item->clipType(), id, producerParams, filterParams, consumerParams, extraParams);
- if (autoAdd) {
- job->setAddClipToProject(true);
- //qDebug()<<"// ADDING TRUE";
- }
- else qDebug()<<"// ADDING FALSE!!!";
-
- if (job->isExclusive() && hasPendingJob(id, job->jobType)) {
- delete job;
- return;
- }
- job->description = description;
- m_jobList.append(job);
- item->setJobStatus(job->jobType, JobWaiting, 0, job->statusMessage());
- slotCheckJobProcess();
- }
-}
-
-
bool JobManager::hasPendingJob(const QString &clipId, AbstractClipJob::JOBTYPE type)
{
QMutexLocker lock(&m_jobMutex);
@@ -404,7 +186,6 @@ void JobManager::slotProcessJobs()
if (job->jobType == AbstractClipJob::MLTJOB) {
MeltJob *jb = static_cast<MeltJob *> (job);
- jb->setProducer(currentClip->producer(), currentClip->url());
if (jb->isProjectFilter())
connect(job, SIGNAL(gotFilterJobResults(QString,int,int,stringMap,stringMap)), this, SLOT(slotGotFilterJobResults(QString,int,int,stringMap,stringMap)));
else
@@ -475,6 +256,9 @@ QList <ProjectClip *> JobManager::filterClips(QList <ProjectClip *>clips, Abstra
if (jobType == AbstractClipJob::TRANSCODEJOB) {
return CutClipJob::filterClips(clips, params);
}
+ else if (jobType == AbstractClipJob::FILTERCLIPJOB) {
+ return FilterJob::filterClips(clips, params);
+ }
}
QStringList JobManager::prepareJobs(QList <ProjectClip *>clips, AbstractClipJob::JOBTYPE jobType, const QStringList params)
@@ -485,8 +269,9 @@ QStringList JobManager::prepareJobs(QList <ProjectClip *>clips, AbstractClipJob:
QMap <ProjectClip *, AbstractClipJob *> jobs;
if (jobType == AbstractClipJob::TRANSCODEJOB) {
jobs = CutClipJob::prepareJob(m_fps, clips, params);
+ } else if (jobType == AbstractClipJob::FILTERCLIPJOB) {
+ jobs = FilterJob::prepareJob(m_fps, clips, params);
}
- qDebug()<<"* * * CREATED: "<<jobs.count()<<" jobs";
if (!jobs.isEmpty()) {
QMapIterator<ProjectClip *, AbstractClipJob *> i(jobs);
while (i.hasNext()) {
@@ -506,7 +291,6 @@ void JobManager::launchJob(ProjectClip *clip, AbstractClipJob *job, bool runQueu
}
m_jobList.append(job);
- qDebug()<<" / / /APPENDED JOB for clip: "<<clip->clipId();
clip->setJobStatus(job->jobType, JobWaiting, 0, job->statusMessage());
if (runQueue) slotCheckJobProcess();
}
diff --git a/src/project/jobs/jobmanager.h b/src/project/jobs/jobmanager.h
index eb813f9..62da6e2 100644
--- a/src/project/jobs/jobmanager.h
+++ b/src/project/jobs/jobmanager.h
@@ -109,9 +109,6 @@ private:
double m_fps;
/** @brief Get the list of job names for current clip. */
QStringList getPendingJobs(const QString &id);
- void slotStartFilterJob(const ItemInfo &info, const QString&id, QMap <QString, QString> &filterParams, QMap <QString, QString> &consumerParams, QMap <QString, QString> &extraParams);
- void startClipFilterJob(QList <ProjectClip *> clipList, const QString &filterName);
- void processClipJob(QStringList ids, const QString&destination, bool autoAdd, QMap <QString, QString> producerParams, QMap <QString, QString> filterParams, QMap <QString, QString> consumerParams, const QString &description, QMap <QString, QString> extraParams);
/** @brief Create a proxy for a clip. */
void createProxy(const QString &id);
diff --git a/src/project/jobs/meltjob.cpp b/src/project/jobs/meltjob.cpp
index 5f54676..dee6a37 100644
--- a/src/project/jobs/meltjob.cpp
+++ b/src/project/jobs/meltjob.cpp
@@ -54,16 +54,7 @@ MeltJob::MeltJob(ClipType cType, const QString id, const QMap <QString, QString>
QString consum = m_consumerParams.value("consumer");
if (consum.contains(QLatin1Char(':')))
m_dest = consum.section(QLatin1Char(':'), 1);
-}
-
-void MeltJob::setProducer(Mlt::Producer *producer, const QUrl &url)
-{
- Q_UNUSED(producer)
-
- //FIX stabilize in proxy clips?
- //m_url = QString::fromUtf8(producer->get("resource"));
- //if (m_url == QLatin1String("<playlist>") || m_url == QLatin1String("<tractor>") || m_url == QLatin1String("<producer>"))
- m_url = url.path();
+ m_url = producerParams.value("producer");
}
void MeltJob::startJob()
@@ -168,25 +159,26 @@ void MeltJob::startJob()
}
// Build filter
- m_filter = new Mlt::Filter(*m_profile, filterName.toUtf8().data());
- if (!m_filter || !m_filter->is_valid()) {
- m_errorMessage = i18n("Filter %1 crashed", filterName);
- setStatus(JobCrashed);
- return;
+ if (!filterName.isEmpty()) {
+ m_filter = new Mlt::Filter(*m_profile, filterName.toUtf8().data());
+ if (!m_filter || !m_filter->is_valid()) {
+ m_errorMessage = i18n("Filter %1 crashed", filterName);
+ setStatus(JobCrashed);
+ return;
+ }
+
+ // Process filter params
+ QMapIterator<QString, QString> k(m_filterParams);
+ ignoredProps.clear();
+ ignoredProps << "filter";
+ while (k.hasNext()) {
+ k.next();
+ QString key = k.key();
+ if (!ignoredProps.contains(key)) {
+ m_filter->set(k.key().toUtf8().constData(), k.value().toUtf8().constData());
+ }
+ }
}
-
- // Process filter params
- QMapIterator<QString, QString> k(m_filterParams);
- ignoredProps.clear();
- ignoredProps << "filter";
- while (k.hasNext()) {
- k.next();
- QString key = k.key();
- if (!ignoredProps.contains(key)) {
- m_filter->set(k.key().toUtf8().constData(), k.value().toUtf8().constData());
- }
- }
-
Mlt::Tractor tractor;
Mlt::Playlist playlist;
playlist.append(*m_producer);
@@ -194,7 +186,7 @@ void MeltJob::startJob()
m_consumer->connect(tractor);
m_producer->set_speed(0);
m_producer->seek(0);
- m_producer->attach(*m_filter);
+ if (m_filter) m_producer->attach(*m_filter);
m_showFrameEvent = m_consumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_render);
m_producer->set_speed(1);
m_consumer->run();
diff --git a/src/project/jobs/meltjob.h b/src/project/jobs/meltjob.h
index 3588446..04d2050 100644
--- a/src/project/jobs/meltjob.h
+++ b/src/project/jobs/meltjob.h
@@ -47,7 +47,6 @@ public:
bool addClipToProject;
const QString statusMessage();
void setStatus(ClipJobStatus status);
- void setProducer(Mlt::Producer *producer, const QUrl &url);
void emitFrameNumber(int pos);
/** Make the job work on a project tree clip. */
bool isProjectFilter() const;
diff --git a/src/project/projectlist.cpp b/src/project/projectlist.cpp
index c411bb1..c798ef7 100644
--- a/src/project/projectlist.cpp
+++ b/src/project/projectlist.cpp
@@ -3266,209 +3266,6 @@ void ProjectList::slotStartFilterJob(const ItemInfo &info, const QString&id, QMa
slotCheckJobProcess();
}
-void ProjectList::startClipFilterJob(const QString &filterName, const QString &condition)
-{
- QMap <QString, QString> ids = getConditionalIds(condition);
- QStringList destination;
- QMap<QString, QString>::const_iterator first = ids.constBegin();
- if (first == ids.constEnd()) {
- emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2, ErrorMessage);
- return;
- }
- ProjectItem *item = getItemById(first.key());
- if (!item) {
- emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2, ErrorMessage);
- return;
- }
- if (ids.count() == 1) {
- destination << item->clipUrl().path();
- }
- else {
- destination = ids.values();
- }
- if (filterName == "framebuffer") {
- Mlt::Profile profile;
- QStringList keys = ids.keys();
- int ix = 0;
- foreach(const QString &url, destination) {
- QString prodstring = QString("framebuffer:" + url + "?-1");
- Mlt::Producer *reversed = new Mlt::Producer(profile, prodstring.toUtf8().constData());
- if (!reversed || !reversed->is_valid()) {
- emit displayMessage(i18n("Cannot reverse clip"), -2, ErrorMessage);
- continue;
- }
- QString dest = url + ".mlt";
- if (QFile::exists(dest)) {
- if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", dest)) == KMessageBox::No) continue;
- }
- Mlt::Consumer *cons = new Mlt::Consumer(profile, "xml", dest.toUtf8().constData());
- if (cons == NULL || !cons->is_valid()) {
- emit displayMessage(i18n("Cannot render reversed clip"), -2, ErrorMessage);
- continue;
- }
- Mlt::Playlist list;
- list.insert_at(0, reversed, 0);
- delete reversed;
- cons->connect(list);
- cons->run();
- delete cons;
- QString groupId;
- QString groupName;
- //TODO
- /*DocClipBase *base = m_doc->clipManager()->getClipById(keys.at(ix));
- if (base) {
- groupId = base->getProperty("groupid");
- groupName = base->getProperty("groupname");
- }
- */
- emit addClip(dest, groupId, groupName);
- ix++;
- }
- return;
- }
-
- if (filterName == "motion_est") {
- // Show config dialog
- QPointer<QDialog> d = new QDialog(this);
- Ui::SceneCutDialog_UI ui;
- ui.setupUi(d);
- // Set up categories
- for (int i = 0; i < 5; ++i) {
- ui.marker_type->insertItem(i, i18n("Category %1", i));
- ui.marker_type->setItemData(i, CommentedTime::markerColor(i), Qt::DecorationRole);
- }
- ui.marker_type->setCurrentIndex(KdenliveSettings::default_marker_type());
- if (d->exec() != QDialog::Accepted) {
- delete d;
- return;
- }
- // Autosplit filter
- QMap <QString, QString> producerParams = QMap <QString, QString> ();
- QMap <QString, QString> filterParams = QMap <QString, QString> ();
- QMap <QString, QString> consumerParams = QMap <QString, QString> ();
-
- // Producer params
- // None
-
- // Filter params, use a smaller region of the image to speed up operation
- // In fact, it's faster to rescale whole image than using part of it (bounding=\"25%x25%:15%x15\")
- filterParams.insert("filter", filterName);
- filterParams.insert("shot_change_list", "0");
- filterParams.insert("denoise", "0");
-
- // Consumer
- consumerParams.insert("consumer", "null");
- consumerParams.insert("all", "1");
- consumerParams.insert("terminate_on_pause", "1");
- consumerParams.insert("real_time", "-1");
- // We just want to find scene change, set all mathods to the fastests
- consumerParams.insert("rescale", "nearest");
- consumerParams.insert("deinterlace_method", "onefield");
- consumerParams.insert("top_field_first", "-1");
-
- // Extra
- QMap <QString, QString> 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");
- }
- if (ui.zone_only->isChecked()) {
- // We want to analyze only clip zone
- extraParams.insert("zoneonly", "1");
- }
- if (ui.add_markers->isChecked()) {
- // We want to create markers
- extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex()));
- }
- if (ui.cut_scenes->isChecked()) {
- // We want to cut scenes
- extraParams.insert("cutscenes", "1");
- }
- delete d;
- processClipJob(ids.keys(), QString(), false, producerParams, filterParams, consumerParams, i18n("Auto split"), extraParams);
- }
- else {
- QPointer<ClipStabilize> d = new ClipStabilize(destination, filterName);
- if (d->exec() == QDialog::Accepted) {
- QMap <QString, QString> extraParams;
- extraParams.insert("producer_profile", "1");
- processClipJob(ids.keys(), d->destination(), d->autoAddClip(), d->producerParams(), d->filterParams(), d->consumerParams(), d->desc(), extraParams);
- }
- delete d;
- }
-}
-
-void ProjectList::processClipJob(QStringList ids, const QString&destination, bool autoAdd, QMap <QString, QString> producerParams, QMap <QString, QString> filterParams, QMap <QString, QString> consumerParams, const QString &description, QMap <QString, QString> extraParams)
-{
- // in and out
- int in = 0;
- int out = -1;
-
- // filter name
- QString filterName = filterParams.value("filter");
-
- // consumer name
- QString consumerName = consumerParams.value("consumer");
-
- foreach(const QString&id, ids) {
- ProjectItem *item = getItemById(id);
- if (!item) continue;
- if (extraParams.contains("zoneonly")) {
- // Analyse clip zone only, remove in / out and replace with zone
- QPoint zone = item->referencedClip()->zone();
- in = zone.x();
- out = zone.y();
- }
- producerParams.insert("in", QString::number(in));
- producerParams.insert("out", QString::number(out));
-
- if (ids.count() == 1) {
- // We only have one clip to process
- if (filterName == "vidstab") {
- // Append a 'filename' parameter for saving vidstab data
- QUrl trffile = QUrl::fromLocalFile(destination + ".trf");
- filterParams.insert("filename", trffile.path());
- consumerParams.insert("consumer", consumerName + ':' + destination);
- } else {
- consumerParams.insert("consumer", consumerName + ':' + destination);
- }
- }
- else {
- // We have several clips to process
- QString mltfile = destination + item->clipUrl().fileName() + ".mlt";
- if (filterName == "vidstab") {
- // Append a 'filename' parameter for saving each vidstab data
- QUrl trffile = QUrl::fromLocalFile(mltfile + ".trf");
- filterParams.insert("filename", trffile.path());
- consumerParams.insert("consumer", consumerName + ':' + mltfile);
- } else {
- consumerParams.insert("consumer", consumerName + ':' + mltfile);
- }
- }
- MeltJob *job = new MeltJob(item->clipType(), id, producerParams, filterParams, consumerParams, extraParams);
- if (autoAdd) {
- job->setAddClipToProject(true);
- //qDebug()<<"// ADDING TRUE";
- }
- else qDebug()<<"// ADDING FALSE!!!";
-
- if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
- delete job;
- return;
- }
- job->description = description;
- m_jobList.append(job);
- setJobStatus(item, job->jobType, JobWaiting, 0, job->statusMessage());
- slotCheckJobProcess();
- }
-}
-
-
void ProjectList::slotPrepareJobsMenu()
{
ProjectItem *item;
diff --git a/src/project/projectlist.h b/src/project/projectlist.h
index 861420c..ff1caba 100644
--- a/src/project/projectlist.h
+++ b/src/project/projectlist.h
@@ -154,8 +154,6 @@ public:
void clearSelection();
/** @brief Print required overlays over clip thumb (proxy, stabilized,...). */
void processThumbOverlays(ProjectItem *item, QPixmap &pix);
- /** @brief Start an MLT process job. */
- void startClipFilterJob(const QString &filterName, const QString &condition);
/** @brief Set current document for the project tree. */
void setDocument(KdenliveDoc *doc);
@@ -294,8 +292,6 @@ private:
void discardJobs(const QString &id, AbstractClipJob::JOBTYPE type = AbstractClipJob::NOJOBTYPE);
/** @brief Get the list of job names for current clip. */
QStringList getPendingJobs(const QString &id);
- /** @brief Start an MLT process job. */
- void processClipJob(QStringList ids, const QString&destination, bool autoAdd, QMap <QString, QString> producerParams, QMap <QString, QString> filterParams, QMap <QString, QString> consumerParams, const QString &description, stringMap extraParams = stringMap());
/** @brief Create rounded shape pixmap for project tree thumb. */
QPixmap roundedPixmap(const QImage &img);
QPixmap roundedPixmap(const QPixmap &source);