#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;
}
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();
class KdenliveDoc;
class DocClipBase;
+namespace Mlt {
+class Producer;
+};
+
class ClipManager: public QObject {
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 */
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");
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()) {
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);
}
}
}
+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 !!!!!!!!!!!!!!!!";
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 */
/** 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);
QMap <QString, QString> properties() const;
QMap <QString, QString> metadata() const;
+
signals:
void getAudioThumbs();
void gotAudioData();
}
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);
}
}
}
}
+void KdenliveDoc::updatePreviewSettings() {
+ m_clipManager->updatePreviewSettings();
+ m_render->updatePreviewSettings();
+ m_clipManager->resetProducersList(m_render->producersList());
+
+}
+
Render *KdenliveDoc::renderer() {
return m_render;
}
void setZone(int start, int end);
QPoint zone() const;
void setSceneList();
+ void updatePreviewSettings();
private:
KUrl m_url;
<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">
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() {
signals:
void customChanged();
void doResetProfile();
+ void updatePreviewSettings();
};
m_dar = producer->profile()->dar();
}
+void KThumb::clearProducer() {
+ m_producer = NULL;
+}
+
bool KThumb::hasProducer() const {
return m_producer != NULL;
}
void setProducer(Mlt::Producer *producer);
void askForAudioThumbs(const QString &id);
bool hasProducer() const;
+ void clearProducer();
void updateThumbUrl(const QString &hash);
public slots:
}
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;
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();
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);
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);
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) {
}
-/*void MainWindow::slotUpdatePreviewSettings() {
- //TODO: perform operation on all open documents
- m_activeDocument->clipManager()->updatePreviewSettings();
-}*/
-
void MainWindow::slotSwitchVideoThumbs() {
KdenliveSettings::setVideothumbnails(!KdenliveSettings::videothumbnails());
void slotRunWizard();
void generateClip();
void slotZoneMoved(int start, int end);
- //void slotUpdatePreviewSettings();
+ void slotUpdatePreviewSettings();
};
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()));
}
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"
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... */
<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>