]> git.sesse.net Git - kdenlive/commitdiff
* New config option for preview: disable B Frame decoding on h.264:
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 13 Jan 2009 00:18:23 +0000 (00:18 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 13 Jan 2009 00:18:23 +0000 (00:18 +0000)
http://www.kdenlive.org:80/mantis/view.php?id=494

svn path=/branches/KDE4/; revision=2906

17 files changed:
src/clipmanager.cpp
src/clipmanager.h
src/docclipbase.cpp
src/docclipbase.h
src/kdenlivedoc.cpp
src/kdenlivedoc.h
src/kdenlivesettings.kcfg
src/kdenlivesettingsdialog.cpp
src/kdenlivesettingsdialog.h
src/kthumb.cpp
src/kthumb.h
src/mainwindow.cpp
src/mainwindow.h
src/monitor.cpp
src/renderer.cpp
src/renderer.h
src/widgets/configsdl_ui.ui

index e47b500f36fdac68c7a89c31bb1f50508c86142c..62c264395e5a465601f8ddecdd479fcd52539a02 100644 (file)
@@ -26,6 +26,8 @@
 #include "docclipbase.h"
 #include "kdenlivedoc.h"
 
+#include <mlt++/Mlt.h>
+
 ClipManager::ClipManager(KdenliveDoc *doc): m_doc(doc), m_audioThumbsEnabled(false), m_audioThumbsQueue(QList <QString> ()), m_generatingAudioId(QString()) {
     m_clipIdCounter = 1;
 }
@@ -147,6 +149,39 @@ DocClipBase *ClipManager::getClipByResource(QString resource) {
     return NULL;
 }
 
+void ClipManager::updatePreviewSettings() {
+    for (int i = 0; i < m_clipList.count(); i++) {
+        if (m_clipList.at(i)->clipType() == AV || m_clipList.at(i)->clipType() == VIDEO) {
+            if (m_clipList.at(i)->producerProperty("meta.media.0.codec.name") == "h264") {
+                if (KdenliveSettings::dropbframes()) {
+                    m_clipList[i]->setProducerProperty("skip_loop_filter", "all");
+                    m_clipList[i]->setProducerProperty("skip_frame", "bidir");
+                } else {
+                    m_clipList[i]->setProducerProperty("skip_loop_filter", "");
+                    m_clipList[i]->setProducerProperty("skip_frame", "");
+                }
+            }
+        }
+    }
+}
+
+void ClipManager::resetProducersList(QList <Mlt::Producer *> prods) {
+    for (int i = 0; i < m_clipList.count(); i++) {
+        if (m_clipList.at(i)->numReferences() > 0) {
+            m_clipList.at(i)->deleteProducers();
+        }
+    }
+    QString id;
+    for (int i = 0; i < prods.count(); i++) {
+        id = prods.at(i)->get("id");
+        if (id.contains('_')) id = id.section('_', 0, 0);
+        DocClipBase *clip = getClipById(id);
+        if (clip) {
+            clip->setProducer(prods.at(i));
+            kDebug() << "// // // REPLACE CLIP: " << id;
+        }
+    }
+}
 
 void ClipManager::slotAddClipList(const KUrl::List urls, const QString group, const QString &groupId) {
     QUndoCommand *addClips = new QUndoCommand();
index 2d8c5fb7e8e39c21754be0f5c6c4a15d17c81f4d..3b42db0c2ce676d26dd3c514f797f6a2e5bf3be1 100644 (file)
 class KdenliveDoc;
 class DocClipBase;
 
+namespace Mlt {
+class Producer;
+};
+
 class ClipManager: public QObject {
 Q_OBJECT public:
 
@@ -65,6 +69,10 @@ Q_OBJECT public:
     void endAudioThumbsGeneration(const QString &requestedId);
     void askForAudioThumb(const QString &id);
     QString projectFolder() const;
+    void resetProducersList(QList <Mlt::Producer *> prods);
+
+public slots:
+    void updatePreviewSettings();
 
 private:   // Private attributes
     /** the list of clips in the document */
index a9e5d5442d3e9c15513fd484a42efa3729f990af..e0f98851a0c86dc3da8121c1debfdb50dd61db6e 100644 (file)
@@ -370,6 +370,12 @@ QString DocClipBase::markerComment(GenTime t) {
     return QString::null;
 }
 
+void DocClipBase::deleteProducers() {
+    qDeleteAll(m_baseTrackProducers);
+    m_baseTrackProducers.clear();
+    if (m_thumbProd) m_thumbProd->clearProducer();
+}
+
 void DocClipBase::setProducer(Mlt::Producer *producer) {
     if (producer == NULL) return;
     QString id = producer->get("id");
@@ -398,9 +404,8 @@ Mlt::Producer *DocClipBase::producer(int track) {
     if (track == -1 || (m_clipType != AUDIO && m_clipType != AV)) {
         if (m_baseTrackProducers.count() == 0) return NULL;
         int i;
-        for (i = 0; i < m_baseTrackProducers.count(); i++)
-            if (m_baseTrackProducers.at(i) != NULL) break;
-        if (i < m_baseTrackProducers.count()) return m_baseTrackProducers.at(i);
+        for (int i = 0; i < m_baseTrackProducers.count(); i++)
+            if (m_baseTrackProducers.at(i) != NULL) return m_baseTrackProducers.at(i);
         return NULL;
     }
     if (track >= m_baseTrackProducers.count()) {
@@ -421,6 +426,10 @@ Mlt::Producer *DocClipBase::producer(int track) {
         char *tmp = (char *) qstrdup(QString(getId() + '_' + QString::number(track)).toUtf8().data());
         m_baseTrackProducers[track]->set("id", tmp);
         delete[] tmp;
+        if (KdenliveSettings::dropbframes()) {
+            m_baseTrackProducers[track]->set("skip_loop_filter", "all");
+            m_baseTrackProducers[track]->set("skip_frame", "bidir");
+        }
     }
     return m_baseTrackProducers.at(track);
 }
@@ -439,6 +448,18 @@ void DocClipBase::setProducerProperty(const char *name, const char *data) {
     }
 }
 
+QString DocClipBase::producerProperty(const char *name) const {
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i) != NULL) {
+            char *tmp = m_baseTrackProducers.at(i)->get(name);
+            QString result = QString(tmp);
+            return result;
+        }
+    }
+    return QString();
+}
+
+
 void DocClipBase::slotRefreshProducer() {
     if (m_baseTrackProducers.count() == 0) return;
     kDebug() << "////////////   REFRESH CLIP !!!!!!!!!!!!!!!!";
index 77352f9b47b16b9ad3be6d97e78f262fdc41c283..1527627620a414242a62040863705a06d0ec71cf 100644 (file)
@@ -167,6 +167,9 @@ Q_OBJECT public:
     void askForAudioThumbs();
     QString getClipHash() const;
     void refreshThumbUrl();
+    QString producerProperty(const char *name) const;
+    void setProducerProperty(const char *name, const char *data);
+    void deleteProducers();
 
 private:   // Private attributes
     /** The name of this clip */
@@ -200,7 +203,6 @@ private:   // Private attributes
     /** Create connections for audio thumbnails */
     void slotCreateAudioTimer();
     void slotRefreshProducer();
-    void setProducerProperty(const char *name, const char *data);
     void setProducerProperty(const char *name, int data);
     void getFileHash(const QString &url);
 
@@ -224,6 +226,7 @@ public slots:
     QMap <QString, QString> properties() const;
     QMap <QString, QString> metadata() const;
 
+
 signals:
     void getAudioThumbs();
     void gotAudioData();
index 381ff6415d317b95dd38984bc1199bd7d9afa6fe..0ab198684d8d05fc08d9be58f7fac93ce5a0dca6 100644 (file)
@@ -327,7 +327,13 @@ void KdenliveDoc::slotAutoSave() {
         }
         kDebug() << "// AUTOSAVE FILE: " << m_autosave->fileName();
         QDomDocument doc;
-        doc.setContent(m_render->sceneList());
+        if (KdenliveSettings::dropbframes()) {
+            KdenliveSettings::setDropbframes(false);
+            m_clipManager->updatePreviewSettings();
+            doc.setContent(m_render->sceneList());
+            KdenliveSettings::setDropbframes(true);
+            m_clipManager->updatePreviewSettings();
+        } else doc.setContent(m_render->sceneList());
         saveSceneList(m_autosave->fileName(), doc);
     }
 }
@@ -1039,6 +1045,13 @@ void KdenliveDoc::checkProjectClips() {
     }
 }
 
+void KdenliveDoc::updatePreviewSettings() {
+    m_clipManager->updatePreviewSettings();
+    m_render->updatePreviewSettings();
+    m_clipManager->resetProducersList(m_render->producersList());
+
+}
+
 Render *KdenliveDoc::renderer() {
     return m_render;
 }
index 45d0aae65a65bc0db07d099f2bbaad00a6a19f34..ccc4ba6072c9d4f26765ad682a4acf92bf7d87bb 100644 (file)
@@ -121,6 +121,7 @@ Q_OBJECT public:
     void setZone(int start, int end);
     QPoint zone() const;
     void setSceneList();
+    void updatePreviewSettings();
 
 private:
     KUrl m_url;
index e417469f0336486b71d53db9b9f8a0db4b106003..6237aa20edba71e5eb93e1804ddfffb1917032b5 100644 (file)
       <default></default>
     </entry>
 
+    <entry name="dropbframes" type="Bool">
+      <label>Drop B Frames on H.264 clips for faster playback (For monitor preview only).</label>
+      <default>false</default>
+    </entry>
   </group>
 
   <group name="env">
index 7796b990e74ce21c02fad41ad4f2a142baaa30ff..36a1b048255180391e249a11ba8e1a57150bd087 100644 (file)
@@ -395,8 +395,15 @@ void KdenliveSettingsDialog::updateSettings() {
         resetProfile = true;
     }
 
+    bool updatePreview = false;
+    if (m_configSdl.kcfg_dropbframes->isChecked() != KdenliveSettings::dropbframes()) {
+        KdenliveSettings::setDropbframes(m_configSdl.kcfg_dropbframes->isChecked());
+        updatePreview = true;
+    }
+
     KConfigDialog::updateSettings();
     if (resetProfile) emit doResetProfile();
+    if (updatePreview) emit updatePreviewSettings();
 }
 
 void KdenliveSettingsDialog::slotUpdateDisplay() {
index 640ef95383edde1a22e58f6aa5868195941f133b..b9e45761e6c8cab333e66dd5a224f115dcbdef35 100644 (file)
@@ -82,6 +82,7 @@ private:
 signals:
     void customChanged();
     void doResetProfile();
+    void updatePreviewSettings();
 };
 
 
index 70864a3e133d70c4548e0d54f7a5d511e28d3508..a836be141d614e0e1df2e2d912119a24a45f4539 100644 (file)
@@ -144,6 +144,10 @@ void KThumb::setProducer(Mlt::Producer *producer) {
     m_dar = producer->profile()->dar();
 }
 
+void KThumb::clearProducer() {
+    m_producer = NULL;
+}
+
 bool KThumb::hasProducer() const {
     return m_producer != NULL;
 }
index 892f4d6c7b34bab08cf0a45b8b8a73029c9ebbd1..f571bdbef14656dc57de19c798205aa23c29b8ba 100644 (file)
@@ -83,6 +83,7 @@ Q_OBJECT public:
     void setProducer(Mlt::Producer *producer);
     void askForAudioThumbs(const QString &id);
     bool hasProducer() const;
+    void clearProducer();
     void updateThumbUrl(const QString &hash);
 
 public slots:
index 136e61ece619d59b8bb244a5c1d10d0ecc6f0c98..98937a2ad4622a25a5083f364710712058502d6f 100644 (file)
@@ -1135,7 +1135,15 @@ void MainWindow::closeCurrentDocument() {
 }
 
 bool MainWindow::saveFileAs(const QString &outputFileName) {
-    QDomDocument currentSceneList = m_projectMonitor->sceneList();
+    QDomDocument currentSceneList;
+    if (KdenliveSettings::dropbframes()) {
+        KdenliveSettings::setDropbframes(false);
+        m_activeDocument->clipManager()->updatePreviewSettings();
+        currentSceneList = m_projectMonitor->sceneList();
+        KdenliveSettings::setDropbframes(true);
+        m_activeDocument->clipManager()->updatePreviewSettings();
+    } else currentSceneList = m_projectMonitor->sceneList();
+
     if (m_activeDocument->saveSceneList(outputFileName, currentSceneList) == false)
         return false;
 
@@ -1367,6 +1375,7 @@ void MainWindow::slotEditProjectSettings() {
             m_monitorManager->resetProfiles(m_activeDocument->timecode());
             if (m_renderWidget) m_renderWidget->setProfile(m_activeDocument->mltProfile());
             m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
+            m_activeDocument->clipManager()->resetProducersList(m_projectMonitor->render->producersList());
 
             // We need to desactivate & reactivate monitors to get a refresh
             m_monitorManager->switchMonitors();
@@ -1403,7 +1412,15 @@ void MainWindow::slotDoRender(const QString &dest, const QString &render, const
     temp.setAutoRemove(false);
     temp.setSuffix(".westley");
     if (temp.open()) {
-        m_projectMonitor->saveSceneList(temp.fileName());
+
+        if (KdenliveSettings::dropbframes()) {
+            KdenliveSettings::setDropbframes(false);
+            m_activeDocument->clipManager()->updatePreviewSettings();
+            m_projectMonitor->saveSceneList(temp.fileName());
+            KdenliveSettings::setDropbframes(true);
+            m_activeDocument->clipManager()->updatePreviewSettings();
+        } else m_projectMonitor->saveSceneList(temp.fileName());
+
         QStringList args;
         args << "-erase";
         if (zoneOnly) args << "in=" + QString::number(in) << "out=" + QString::number(out);
@@ -1594,6 +1611,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     setCaption(doc->description(), doc->isModified());
     m_saveAction->setEnabled(doc->isModified());
     m_activeDocument = doc;
+    if (KdenliveSettings::dropbframes()) slotUpdatePreviewSettings();
 
     // set tool to select tool
     m_buttonSelectTool->setChecked(true);
@@ -1624,11 +1642,19 @@ void MainWindow::slotPreferences(int page, int option) {
     KdenliveSettingsDialog* dialog = new KdenliveSettingsDialog(this);
     connect(dialog, SIGNAL(settingsChanged(const QString&)), this, SLOT(updateConfiguration()));
     connect(dialog, SIGNAL(doResetProfile()), m_monitorManager, SLOT(slotResetProfiles()));
+    connect(dialog, SIGNAL(updatePreviewSettings()), this, SLOT(slotUpdatePreviewSettings()));
     //connect(dialog, SIGNAL(updatePreviewSettings()), this, SLOT(slotUpdatePreviewSettings()));
     dialog->show();
     if (page != -1) dialog->showPage(page, option);
 }
 
+void MainWindow::slotUpdatePreviewSettings() {
+    if (m_activeDocument) {
+        m_clipMonitor->slotSetXml(NULL, 0);
+        m_activeDocument->updatePreviewSettings();
+    }
+}
+
 void MainWindow::updateConfiguration() {
     //TODO: we should apply settings to all projects, not only the current one
     if (m_activeTimeline) {
@@ -1645,11 +1671,6 @@ void MainWindow::updateConfiguration() {
 
 }
 
-/*void MainWindow::slotUpdatePreviewSettings() {
-    //TODO: perform operation on all open documents
-    m_activeDocument->clipManager()->updatePreviewSettings();
-}*/
-
 
 void MainWindow::slotSwitchVideoThumbs() {
     KdenliveSettings::setVideothumbnails(!KdenliveSettings::videothumbnails());
index 7e9f00a326521df01fbdc71d16a81b70688d574e..3d49259ba8514898fbb75cebba3b286c371a25ca 100644 (file)
@@ -284,7 +284,7 @@ private slots:
     void slotRunWizard();
     void generateClip();
     void slotZoneMoved(int start, int end);
-    //void slotUpdatePreviewSettings();
+    void slotUpdatePreviewSettings();
 };
 
 
index c04369434e8e2a41c96388dd5a60724524c40b20..c98060e1b4856a9f02754bfe2a3fd5d13909c975 100644 (file)
@@ -602,14 +602,20 @@ void Monitor::slotLoopZone() {
 void Monitor::slotSetXml(DocClipBase *clip, const int position) {
     if (render == NULL) return;
     activateMonitor();
-    if (!clip) return;
-    if (clip != m_currentClip && clip->producer() != NULL) {
-        m_currentClip = clip;
-        render->setProducer(clip->producer(), position);
-        //m_ruler->slotNewValue(0);
-        //adjustRulerSize(clip->producer()->get_playtime());
-        //m_timePos->setText("00:00:00:00");
-        m_position = position;
+    if (!clip) {
+        kDebug() << "// SETTING NULL CLIP";
+        m_currentClip = NULL;
+        return;
+    }
+    if (clip != m_currentClip) {
+        if (clip->producer() != NULL) {
+            m_currentClip = clip;
+            render->setProducer(clip->producer(), position);
+            //m_ruler->slotNewValue(0);
+            //adjustRulerSize(clip->producer()->get_playtime());
+            //m_timePos->setText("00:00:00:00");
+            m_position = position;
+        }
     } else if (position != -1) render->seek(GenTime(position, render->fps()));
 }
 
index 696495d7051e07854d53a201f542745a67b9aacc..d31b98ffe7d4658a92f83dd5f6537526738a7b71 100644 (file)
@@ -2865,5 +2865,20 @@ void Render::mltDeleteTrack(int ix) {
     blockSignals(false);
 }
 
+
+void Render::updatePreviewSettings() {
+    kDebug() << "////// RESTARTING CONSUMER";
+    if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
+    m_mltConsumer->purge();
+    QString scene = sceneList();
+    int pos = 0;
+    if (m_mltProducer) {
+        pos = m_mltProducer->position();
+        delete m_mltProducer;
+    }
+    m_mltProducer = NULL;
+    setSceneList(scene, pos);
+}
+
 #include "renderer.moc"
 
index a579bdc5861ff80461619f421aaaff53dff308d4..3940b943ef4b7df6f2b14f783d098e43ad751563 100644 (file)
@@ -183,6 +183,7 @@ Q_OBJECT public:
     int mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod);
 
     QList <Mlt::Producer *> producersList();
+    void updatePreviewSettings();
 
 private:   // Private attributes & methods
     /** The name of this renderer - useful to identify the renderes by what they do - e.g. background rendering, workspace monitor, etc... */
index 16a0d3883ba690165a035165b3a75c6a0d638554..5163b81765e1242bf305be060531bd14a4244019 100644 (file)
@@ -5,11 +5,11 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>261</width>
-    <height>129</height>
+    <width>400</width>
+    <height>228</height>
    </rect>
   </property>
-  <layout class="QGridLayout" name="gridLayout" >
+  <layout class="QGridLayout" name="gridLayout_2" >
    <item row="0" column="0" colspan="2" >
     <widget class="QLabel" name="label_2" >
      <property name="text" >
    <item row="3" column="1" >
     <widget class="KComboBox" name="kcfg_audio_device" />
    </item>
-   <item row="4" column="1" >
+   <item row="4" column="0" colspan="2" >
+    <widget class="QGroupBox" name="groupBox" >
+     <property name="title" >
+      <string>Monitor Preview Speedup Settings</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout" >
+      <item row="0" column="0" >
+       <widget class="QCheckBox" name="kcfg_dropbframes" >
+        <property name="text" >
+         <string>Drop B frames on H.264 clips</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="5" column="1" >
     <spacer name="verticalSpacer" >
      <property name="orientation" >
       <enum>Qt::Vertical</enum>