From 5c45d48096ef7528e3dd9b910ff1bf14d234d26a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 5 Mar 2008 12:34:25 +0000 Subject: [PATCH] better handling of document switching (still some crashes) svn path=/branches/KDE4/; revision=2000 --- src/clipmanager.cpp | 3 ++ src/clipmanager.h | 1 + src/kdenlivedoc.cpp | 27 +++-------------- src/kdenlivedoc.h | 3 +- src/kthumb.cpp | 6 ++-- src/mainwindow.cpp | 24 ++++++++++++--- src/mainwindow.h | 1 + src/projectlist.cpp | 24 +++++++++------ src/renderer.cpp | 71 +++++++++++++++++++++++++++++++++------------ src/renderer.h | 7 ++--- 10 files changed, 103 insertions(+), 64 deletions(-) diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index 2dd72625..8eff513a 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -45,6 +45,9 @@ void ClipManager::setThumbsProgress(KUrl url, int progress) { m_doc->setThumbsProgress(url, progress); } +QList ClipManager::documentClipList() { + return m_clipList; +} void ClipManager::addClip(DocClipBase *clip) { m_clipList.append(clip); diff --git a/src/clipmanager.h b/src/clipmanager.h index 138c3ffb..f6d15b26 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -54,6 +54,7 @@ Q_OBJECT public: void slotDeleteClip(uint clipId); void setThumbsProgress(KUrl url, int progress); void checkAudioThumbs(); + QList documentClipList(); private: // Private attributes /** the list of clips in the document */ diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 35e50d31..c507231b 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -101,6 +101,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, MltVideoProfile profile, QWidget *pare doc.appendChild(tractor); } + m_scenelist = m_document.toString(); if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true); else m_timecode.setFormat((int) m_fps); } @@ -128,7 +129,7 @@ KUndoStack *KdenliveDoc::commandStack() { void KdenliveDoc::setRenderer(Render *render) { m_render = render; - if (m_render) m_render->setSceneList(m_document); + if (m_render) m_render->setSceneList(m_scenelist); } Render *KdenliveDoc::renderer() { @@ -208,28 +209,8 @@ QDomNodeList KdenliveDoc::producersList() { return m_document.elementsByTagName("producer"); } -void KdenliveDoc::setProducers(QDomElement doc) { - QDomNode kdenlivedocument = m_document.elementsByTagName("kdenlivedoc").item(0); - - QDomNodeList list = m_document.elementsByTagName("producer"); - int ct = list.count(); - kDebug() << "DELETING CHILD PRODUCERS: " << ct; - for (int i = ct; i > 0; i--) { - kdenlivedocument.removeChild(list.item(i)); - } - - QDomNode n = doc.firstChild(); - ct = 0; - while (!n.isNull()) { - QDomElement e = n.toElement(); // try to convert the node to an element. - if (!e.isNull() && e.tagName() == "producer") { - kdenlivedocument.appendChild(m_document.importNode(e, true)); - ct++; - } - n = n.nextSibling(); - } - kDebug() << "ADDING CHILD PRODS: " << ct << "\n"; - //kDebug()<sceneList(); } double KdenliveDoc::fps() { diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index 78839441..e5577737 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -47,7 +47,7 @@ Q_OBJECT public: int width(); int height(); KUrl url(); - void setProducers(QDomElement doc); + void backupMltPlaylist(); Timecode timecode(); QDomDocument toXml(); void setRenderer(Render *render); @@ -82,6 +82,7 @@ private: QDomDocument generateSceneList(); ClipManager *m_clipManager; MltVideoProfile m_profile; + QString m_scenelist; public slots: diff --git a/src/kthumb.cpp b/src/kthumb.cpp index 92ff342d..e13c2d2e 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -76,9 +76,9 @@ void MyThread::run() { if (KdenliveSettings::normaliseaudiothumbs()) { - Mlt::Filter m_convert(prof,"volume"); - m_convert.set("gain", "normalise"); - m_producer.attach(m_convert); + Mlt::Filter m_convert(prof, "volume"); + m_convert.set("gain", "normalise"); + m_producer.attach(m_convert); } //QApplication::postEvent(m_parent, new ProgressEvent(-1, (QEvent::Type)10005)); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 322324e0..ef4e096f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -60,7 +60,7 @@ MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent), - fileName(QString()), m_activeDocument(NULL), m_commandStack(NULL) { + fileName(QString()), m_activeDocument(NULL), m_activeTimeline(NULL), m_commandStack(NULL) { parseProfiles(); m_timelineArea = new KTabWidget(this); m_timelineArea->setHoverCloseButton(true); @@ -436,9 +436,26 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha kDebug() << "/////////////////// CONNECTING DOC TO PROJECT VIEW ////////////////"; if (m_activeDocument) { if (m_activeDocument == doc) return; - m_activeDocument->setProducers(m_projectList->producersList()); + m_activeDocument->backupMltPlaylist(); + if (m_activeTimeline) { + disconnect(m_projectMonitor, SIGNAL(renderPosition(int)), m_activeTimeline, SLOT(moveCursorPos(int))); + disconnect(m_projectMonitor, SIGNAL(durationChanged(int)), m_activeTimeline->projectView(), SLOT(setDuration(int))); + disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *))); + disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int))); + disconnect(m_activeDocument, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int))); + disconnect(m_activeDocument, SIGNAL(deletTimelineClip(int)), m_activeTimeline, SLOT(slotDeleteClip(int))); + disconnect(m_activeDocument, SIGNAL(thumbsProgress(KUrl, int)), this, SLOT(slotGotProgressInfo(KUrl, int))); + disconnect(m_activeTimeline, SIGNAL(clipItemSelected(ClipItem*)), effectStack, SLOT(slotClipItemSelected(ClipItem*))); + disconnect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement))); + disconnect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement))); + disconnect(effectStack, SIGNAL(changeEffectState(ClipItem*, QDomElement, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, QDomElement, bool))); + disconnect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*))); + } m_activeDocument->setRenderer(NULL); } + m_monitorManager->resetProfiles(doc->profilePath()); + m_projectList->setDocument(doc); + connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor())); connect(trackView, SIGNAL(mousePosition(int)), this, SLOT(slotUpdateMousePosition(int))); connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int))); @@ -454,10 +471,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha connect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement))); connect(effectStack, SIGNAL(changeEffectState(ClipItem*, QDomElement, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, QDomElement, bool))); connect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*))); + m_activeTimeline = trackView; - m_projectList->setDocument(doc); m_monitorManager->setTimecode(doc->timecode()); - m_monitorManager->resetProfiles(doc->profilePath()); doc->setRenderer(m_projectMonitor->render); //m_undoView->setStack(0); m_commandStack = doc->commandStack(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 23dd3462..7a231529 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -63,6 +63,7 @@ private: void setupActions(); QString fileName; KdenliveDoc *m_activeDocument; + TrackView *m_activeTimeline; MonitorManager *m_monitorManager; QDockWidget *projectListDock; diff --git a/src/projectlist.cpp b/src/projectlist.cpp index b2ee5011..0e6a04af 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -337,19 +337,25 @@ void ProjectList::slotAddTitleClip() { //delete dia; } void ProjectList::setDocument(KdenliveDoc *doc) { + listView->clear(); + QList list = doc->clipManager()->documentClipList(); + for (int i = 0; i < list.count(); i++) { + slotAddClip(list.at(i)); + } + m_fps = doc->fps(); m_timecode = doc->timecode(); m_commandStack = doc->commandStack(); m_doc = doc; - QDomNodeList prods = doc->producersList(); - int ct = prods.count(); - kDebug() << "//////////// SETTING DOC, FOUND CLIPS: " << prods.count(); - listView->clear(); - for (int i = 0; i < ct ; i++) { - QDomElement e = prods.item(i).toElement(); - kDebug() << "// IMPORT: " << i << ", :" << e.attribute("id", "non") << ", NAME: " << e.attribute("name", "non"); - if (!e.isNull()) addProducer(e); - } + /* QDomNodeList prods = doc->producersList(); + int ct = prods.count(); + kDebug() << "//////////// SETTING DOC, FOUND CLIPS: " << prods.count(); + listView->clear(); + for (int i = 0; i < ct ; i++) { + QDomElement e = prods.item(i).toElement(); + kDebug() << "// IMPORT: " << i << ", :" << e.attribute("id", "non") << ", NAME: " << e.attribute("name", "non"); + if (!e.isNull()) addProducer(e); + }*/ QTreeWidgetItem *first = listView->topLevelItem(0); if (first) listView->setCurrentItem(first); m_toolbar->setEnabled(true); diff --git a/src/renderer.cpp b/src/renderer.cpp index 597235d2..80c6023e 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -36,6 +36,7 @@ extern "C" { #include #include #include +#include #include "renderer.h" #include "kdenlivesettings.h" @@ -50,9 +51,9 @@ static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr } } -Render::Render(const QString & rendererName, int winid, int extid, QWidget *parent): QObject(parent), m_name(rendererName), m_mltConsumer(NULL), m_mltProducer(NULL), m_mltTextProducer(NULL), m_sceneList(QDomDocument()), m_winid(-1), m_framePosition(0), m_generateScenelist(false), m_isBlocked(true) { - kDebug() << "////////// USING PROFILE: " << qstrdup(KdenliveSettings::current_profile().toUtf8()); - m_mltProfile = new Mlt::Profile((char*) qstrdup(KdenliveSettings::current_profile().toUtf8())); +Render::Render(const QString & rendererName, int winid, int extid, QWidget *parent): QObject(parent), m_name(rendererName), m_mltConsumer(NULL), m_mltProducer(NULL), m_mltTextProducer(NULL), m_winid(-1), m_framePosition(0), m_generateScenelist(false), m_isBlocked(true) { + kDebug() << "////////// USING PROFILE: " << (char *)KdenliveSettings::current_profile().toUtf8().data(); + m_mltProfile = new Mlt::Profile((char*) KdenliveSettings::current_profile().data()); refreshTimer = new QTimer(this); connect(refreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); @@ -118,13 +119,19 @@ int Render::resetProfile(QString profile) { if (!m_mltConsumer) return 0; if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop(); m_mltConsumer->set("refresh", 0); + m_mltConsumer->purge(); //TODO: we should also rebuild filters and delete existing m_mltProfile - m_mltProfile = new Mlt::Profile((char*) qstrdup(profile.toUtf8())); - kDebug() << " + + RESET CONSUMER WITH PROFILE: " << profile; - mlt_properties properties = MLT_CONSUMER_PROPERTIES(m_mltConsumer->get_consumer()); - mlt_properties_set_data(properties, "profile", m_mltProfile->get_profile(), 0, 0, NULL); + + //delete m_mltProfile; + //m_mltProfile = new Mlt::Profile("pal_dv");//(char*) qstrdup(profile.toUtf8())); + kDebug() << " ++++++++++ RESET CONSUMER WITH PROFILE: " << m_mltProfile->width(); + // mlt_properties properties = MLT_CONSUMER_PROPERTIES(m_mltConsumer->get_consumer()); + //mlt_profile prof = m_mltProfile->get_profile(); + //mlt_properties_set_data(properties, "_profile", prof, 0, (mlt_destructor)mlt_profile_close, NULL); + //mlt_properties_set(properties, "profile", "hdv_1080_50i"); + m_mltConsumer->set("profile", (char *) profile.data()); //apply_profile_properties( m_mltProfile, m_mltConsumer->get_consumer(), properties ); - refresh(); + //refresh(); return 1; } @@ -140,7 +147,7 @@ char *Render::decodedString(QString str) { char *t = new char[fn.length() + 1]; strcpy(t, (const char *)fn);*/ - return qstrdup(str.toUtf8().data()); //toLatin1 + return (char *) qstrdup(str.toUtf8().data()); //toLatin1 } //static @@ -425,10 +432,6 @@ void Render::getFileProperties(const QDomElement &xml, int clipId) { if (frame) delete frame; } -QDomDocument Render::sceneList() const { - return m_sceneList; -} - /** Create the producer from the Westley QDomDocument */ void Render::initSceneList() { kDebug() << "-------- INIT SCENE LIST ------_"; @@ -464,13 +467,17 @@ void Render::initSceneList() { setSceneList(doc, 0); } - /** Create the producer from the Westley QDomDocument */ void Render::setSceneList(QDomDocument list, int position) { + setSceneList(list.toString(), position); +} + +/** Create the producer from the Westley QDomDocument */ +void Render::setSceneList(QString playlist, int position) { if (m_winid == -1) return; m_generateScenelist = true; - kWarning() << "////// RENDER, SET SCENE LIST"; + kWarning() << "////// RENDER, SET SCENE LIST: " << playlist; /* @@ -490,7 +497,6 @@ void Render::setSceneList(QDomDocument list, int position) { if (m_mltProducer) { m_mltProducer->set_speed(0.0); - //if (KdenliveSettings::osdtimecode() && m_osdInfo) m_mltProducer->detach(*m_osdInfo); delete m_mltProducer; @@ -498,9 +504,7 @@ void Render::setSceneList(QDomDocument list, int position) { emit stopped(); } - char *tmp = decodedString(list.toString()); - //Mlt::Producer clip(profile, "westley-xml", tmp); - + char *tmp = decodedString(playlist); m_mltProducer = new Mlt::Producer(*m_mltProfile, "westley-xml", tmp); delete[] tmp; //m_mltProducer->optimise(); @@ -538,6 +542,35 @@ void Render::setSceneList(QDomDocument list, int position) { } +/** Create the producer from the Westley QDomDocument */ +QString Render::sceneList() { + if (m_winid == -1) return QString(); + KTemporaryFile temp; + QString result; + + if (temp.open()) { + QString path = temp.fileName(); + char *tmppath = decodedString("westley:" + path); + Mlt::Consumer westleyConsumer(*m_mltProfile , tmppath); + delete[] tmppath; + westleyConsumer.set("terminate_on_pause", 1); + Mlt::Producer prod(m_mltProducer->get_producer()); + westleyConsumer.connect(prod); + westleyConsumer.start(); + + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return QString(); + + QTextStream in(&file); + while (!in.atEnd()) { + result.append(in.readLine()); + } + } + return result; +} + + const double Render::fps() const { return m_fps; } diff --git a/src/renderer.h b/src/renderer.h index 082dda9e..d98b127a 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -93,6 +93,8 @@ Q_OBJECT public: /** Wraps the VEML command of the same name. Sets the current scene list to be list. */ void setSceneList(QDomDocument list, int position = 0); + void setSceneList(QString playlist, int position = 0); + QString sceneList(); /** Wraps the VEML command of the same name. Tells the renderer to play the current scene at the speed specified, relative to normal @@ -143,8 +145,6 @@ Q_OBJECT public: /** Turn on or off on screen display */ void refreshDisplay(); - /** returns the current scenelist */ - QDomDocument sceneList() const; int resetProfile(QString profile); const double fps() const; @@ -187,9 +187,6 @@ private: // Private attributes & methods KUrl m_exportedFile; int exportDuration, firstExportFrame, lastExportFrame; - /** Holds the scenelist to be sent, if pending. */ - QDomDocument m_sceneList; - /** A human-readable description of this renderer. */ QString m_description; int m_winid; -- 2.39.2