]> git.sesse.net Git - kdenlive/commitdiff
Turn transcoding action into clip job (in progress)
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 23 Dec 2011 14:41:55 +0000 (15:41 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 23 Dec 2011 14:41:55 +0000 (15:41 +0100)
src/kdenlivetranscodingrc
src/mainwindow.cpp
src/projectlist.cpp
src/projectlist.h
src/projecttree/cutclipjob.cpp

index 018db4c6913068de9637a6e1854461fb217c2cdf..b4d54169b4cfade91185e590626ea7e76e1b2b21 100644 (file)
@@ -13,9 +13,9 @@ DNxHD 720p 50 fps 175 Mb/s=-s 1280x720 -r 50 -vb 175000k -threads 2 -vcodec dnxh
 DNxHD 720p 50 fps 115 Mb/s=-s 1280x720 -r 50 -vb 175000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
 DNxHD 720p 59.94 fps 220 Mb/s=-s 1280x720 -r 60000/1001 -vb 220000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
 DNxHD 720p 59.94 fps 145 Mb/s=-s 1280x720 -r 60000/1001 -vb 145000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
-Fix MPEG-1=-sameq -acodec copy -vcodec mpeg1video %1.mpg;Fix unplayable MPEG-1 files
-Fix Ogg Theora=-sameq -vcodec libtheora -acodec copy %1.ogv;Fix unplayable OGG Theora files
-Remux MPEG-2 PS/VOB=-vcodec copy -acodec copy %1.mpg;Fix audio sync in MPEG-2 vob files
+Fix MPEG-1=-sameq -acodec copy -vcodec mpeg1video %1.mpg;Fix unplayable MPEG-1 files;;vcodec=mpeg1video
+Fix Ogg Theora=-sameq -vcodec libtheora -acodec copy %1.ogv;Fix unplayable OGG Theora files;;vcodec=theora
+Remux MPEG-2 PS/VOB=-vcodec copy -acodec copy %1.mpg;Fix audio sync in MPEG-2 vob files;;vcodec=mpeg2video
 Lossless Matroska=-sn -vcodec huffyuv -acodec flac %1.mkv;High quality lossless encoding
 Wav 48000Hz=-vn -ar 48000 %1.wav;Extract audio as WAV file;audio
 Remux with MKV=-vcodec copy -acodec copy -sn %1.mkv
index a88ac9e1bc358f4076e4c1410d26ea025a880ada..927df0a90b33a12a7ba7eb2c64f6415eebc2cff1 100644 (file)
@@ -2699,7 +2699,7 @@ void MainWindow::updateConfiguration()
 
     // Update list of transcoding profiles
     loadTranscoders();
-       loadStabilize();
+    loadStabilize();
 #ifdef USE_JOGSHUTTLE
     activateShuttleDevice();
 #endif
@@ -3840,7 +3840,7 @@ void MainWindow::loadTranscoders()
             a = transMenu->addAction(i.key());
         }
         a->setData(data);
-        a->setToolTip(data.at(1));
+        if (data.count() > 1) a->setToolTip(data.at(1));
         connect(a, SIGNAL(triggered()), this, SLOT(slotTranscode()));
     }
 }
@@ -3878,9 +3878,10 @@ void MainWindow::slotTranscode(KUrl::List urls)
         QStringList data = action->data().toStringList();
         params = data.at(0);
         if (data.count() > 1) desc = data.at(1);
-        if (data.count() > 2) condition = data.at(2);
-        urls << m_projectList->getConditionalUrls(condition);
-        urls.removeAll(KUrl());
+        if (data.count() > 3) condition = data.at(3);
+        QStringList ids = m_projectList->getConditionalIds(condition);
+        m_projectList->slotTranscodeClipJob(ids, params, desc);
+        return;
     }
     if (urls.isEmpty()) {
         m_messageLabel->setMessage(i18n("No clip to transcode"), ErrorMessage);
@@ -3889,7 +3890,6 @@ void MainWindow::slotTranscode(KUrl::List urls)
     ClipTranscode *d = new ClipTranscode(urls, params, desc);
     connect(d, SIGNAL(addClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
     d->show();
-    //QProcess::startDetached("ffmpeg", parameters);
 }
 
 void MainWindow::slotTranscodeClip()
index d3584e8e822cc8d1cb5ecc23a224ff95e4cea712..11571061a4bc4de81dae7a68265dfd6d6a9cf716 100644 (file)
@@ -2351,6 +2351,34 @@ KUrl::List ProjectList::getConditionalUrls(const QString &condition) const
     return result;
 }
 
+QStringList ProjectList::getConditionalIds(const QString &condition) const
+{
+    QStringList result;
+    ProjectItem *item;
+    QList<QTreeWidgetItem *> list = m_listView->selectedItems();
+    for (int i = 0; i < list.count(); i++) {
+        if (list.at(i)->type() == PROJECTFOLDERTYPE)
+            continue;
+        if (list.at(i)->type() == PROJECTSUBCLIPTYPE) {
+            // subitem
+            item = static_cast <ProjectItem*>(list.at(i)->parent());
+        } else {
+            item = static_cast <ProjectItem*>(list.at(i));
+        }
+        if (item == NULL || item->type() == COLOR || item->type() == SLIDESHOW || item->type() == TEXT)
+            continue;
+        DocClipBase *clip = item->referencedClip();
+        if (!condition.isEmpty()) {
+            if (condition.startsWith("vcodec") && !clip->hasVideoCodec(condition.section('=', 1, 1)))
+                continue;
+            else if (condition.startsWith("acodec") && !clip->hasAudioCodec(condition.section('=', 1, 1)))
+                continue;
+        }
+        result.append(item->clipId());
+    }
+    return result;
+}
+
 void ProjectList::regenerateTemplate(const QString &id)
 {
     ProjectItem *clip = getItemById(id);
@@ -2591,6 +2619,7 @@ void ProjectList::slotCutClipJob(const QString &id, QPoint zone)
     ui.add_clip->setChecked(KdenliveSettings::add_clip_cut());
     ui.file_url->fileDialog()->setOperationMode(KFileDialog::Saving);
     ui.file_url->setUrl(KUrl(dest));
+    ui.extra_params->setPlainText("-acodec copy -vcodec copy");
     QString mess = i18n("Extracting %1 out of %2", timeOut, Timecode::getStringTimecode(max, clipFps, true));
     ui.info_label->setText(mess);
     if (d->exec() != QDialog::Accepted) {
@@ -2632,6 +2661,42 @@ void ProjectList::slotCutClipJob(const QString &id, QPoint zone)
     slotCheckJobProcess();
 }
 
+void ProjectList::slotTranscodeClipJob(QStringList ids, QString params, QString desc)
+{
+    QStringList existingFiles;
+    foreach(const QString &id, ids) {
+        ProjectItem *item = getItemById(id);
+        if (!item) continue;
+        QString newFile = params.section(' ', -1).replace("%1", item->clipUrl().path());
+        if (QFile::exists(newFile)) existingFiles << newFile;
+    }
+    if (!existingFiles.isEmpty()) {
+        if (KMessageBox::warningContinueCancelList(this, i18n("The transcoding job will overwrite the following files:"), existingFiles) ==  KMessageBox::Cancel) return;
+    }
+    
+    foreach(const QString &id, ids) {
+        ProjectItem *item = getItemById(id);
+        if (!item || !item->referencedClip()) continue;
+        QString src = item->clipUrl().path();
+        QString dest = params.section(' ', -1).replace("%1", src);
+        m_processingProxy.append(dest);
+        QStringList jobParams;
+        jobParams << dest << src << QString() << QString();
+        double clipFps = item->referencedClip()->getProperty("fps").toDouble();
+        if (clipFps == 0) clipFps = m_fps;
+        int max = item->clipMaxDuration();
+        QString duration = QString::number(max);
+        jobParams << duration;
+        jobParams << QString::number(KdenliveSettings::add_clip_cut());
+        jobParams << params.section(' ', 0, -2);
+        CutClipJob *job = new CutClipJob(item->clipType(), id, jobParams);
+        m_jobList.append(job);
+        setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage());
+    }
+    slotCheckJobProcess();
+    
+}
+
 
 void ProjectList::slotCheckJobProcess()
 {        
index 083efce59ce93c9b3e07a6ab5229ce33ff4361f4..d0f181ea1fe5557960ecc7604d4b586e91cbc2d0 100644 (file)
@@ -225,6 +225,8 @@ public:
     void setupGeneratorMenu(const QHash<QString,QMenu*>& menus);
     QString currentClipUrl() const;
     KUrl::List getConditionalUrls(const QString &condition) const;
+    /** @brief Get a list of selected clip Id's that match a condition. */
+    QStringList getConditionalIds(const QString &condition) const;
     QDomDocument generateTemplateXml(QString data, const QString &replaceString);
     void cleanup();
     void trashUnusedClips();
@@ -299,6 +301,7 @@ public slots:
     void slotDeleteProxy(const QString proxyPath);
     /** @brief Start a hard cut clip job. */
     void slotCutClipJob(const QString &id, QPoint zone);
+    void slotTranscodeClipJob(QStringList ids, QString params, QString desc);
 
 private:
     ProjectListView *m_listView;
index 006b82321dd058a8d784726baa3be74fc99f496c..993c9ebb0a9359addaa174ea134d8072effe5f34 100644 (file)
 CutClipJob::CutClipJob(CLIPTYPE cType, const QString &id, QStringList parameters) : AbstractClipJob(CUTJOB, cType, id, parameters)
 {
     jobStatus = JOBWAITING;
-    description = i18n("clip cut");
     m_dest = parameters.at(0);
     m_src = parameters.at(1);
     m_start = parameters.at(2);
     m_end = parameters.at(3);
+    if (m_start.isEmpty()) {
+        // this is a transcoding job
+        description = i18n("Transcode clip");
+    }
+    else description = i18n("Cut clip");
     m_jobDuration = parameters.at(4).toInt();
     addClipToProject = parameters.at(5).toInt();
     if (parameters.count() == 7) m_cutExtraParams = parameters.at(6).simplified();
@@ -44,8 +48,8 @@ QProcess *CutClipJob::startJob(bool *ok)
     if (clipType == AV || clipType == AUDIO || clipType == VIDEO) {
        QStringList parameters;
         parameters << "-i" << m_src;
-        parameters << "-ss" << m_start <<"-t" << m_end;
-        parameters << "-acodec" << "copy" << "-vcodec" << "copy";
+        if (!m_start.isEmpty())
+            parameters << "-ss" << m_start <<"-t" << m_end;
         if (!m_cutExtraParams.isEmpty()) {
             foreach(const QString &s, m_cutExtraParams.split(' '))
                 parameters << s;
@@ -72,12 +76,12 @@ int CutClipJob::processLogInfo()
 {
     if (!m_jobProcess || m_jobDuration == 0 || jobStatus == JOBABORTED) return JOBABORTED;
     QString log = m_jobProcess->readAll();
+    kDebug()<<"// PROgress: "<<log;
     if (!log.isEmpty()) m_errorMessage.append(log + '\n');
     int progress;
     // Parse FFmpeg output
     if (log.contains("frame=")) {
         int progress = log.section("frame=", 1, 1).simplified().section(' ', 0, 0).toInt();
-        kDebug()<<"// PROgress: "<<progress<<", DUR: "<<m_jobDuration;
         return (int) (100.0 * progress / m_jobDuration);
     }
     else if (log.contains("time=")) {
@@ -113,10 +117,12 @@ const QString CutClipJob::statusMessage()
     QString statusInfo;
     switch (jobStatus) {
         case JOBWORKING:
-            statusInfo = i18n("Extracting clip cut");
+            if (m_start.isEmpty()) statusInfo = i18n("Transcoding clip");
+            else statusInfo = i18n("Extracting clip cut");
             break;
         case JOBWAITING:
-            statusInfo = i18n("Waiting - clip cut");
+            if (m_start.isEmpty()) statusInfo = i18n("Waiting - transcode clip");
+            else statusInfo = i18n("Waiting - cut clip");
             break;
         default:
             break;