]> git.sesse.net Git - kdenlive/commitdiff
Try to fix audio mixing bug ( http://www.kdenlive.org:80/mantis/view.php?id=228 )
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 31 Oct 2008 09:42:09 +0000 (09:42 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 31 Oct 2008 09:42:09 +0000 (09:42 +0000)
Warning: this is a large commit with important changes. it probably breaks loading of current kdenlive project files, I will fix this if bugs are reported

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

14 files changed:
src/clipmanager.cpp
src/clipmanager.h
src/customtrackview.cpp
src/docclipbase.cpp
src/docclipbase.h
src/kdenlivedoc.cpp
src/kdenlivedoc.h
src/mainwindow.cpp
src/monitor.cpp
src/monitor.h
src/projectlistview.cpp
src/renderer.cpp
src/renderer.h
src/trackview.cpp

index ad18f93f4e3d19b6e29522d8a43ff05dfb45546b..e8bd52ae5916c6bc3e85637820cacc9754c6752b 100644 (file)
@@ -125,8 +125,9 @@ DocClipBase *ClipManager::getClipAt(int pos) {
     return m_clipList.at(pos);
 }
 
-DocClipBase *ClipManager::getClipById(const QString &clipId) {
+DocClipBase *ClipManager::getClipById(QString clipId) {
     //kDebug() << "++++  CLIP MAN, LOOKING FOR CLIP ID: " << clipId;
+    clipId = clipId.section('_', 0, 0);
     for (int i = 0; i < m_clipList.count(); i++) {
         if (m_clipList.at(i)->getId() == clipId) {
             //kDebug() << "++++  CLIP MAN, FOUND FOR CLIP ID: " << clipId;
index 3fd66c62d7e4f6f54f0efc0b8760c03a12d7bdf3..cfa0565a749261b5556b8625e8d603945ca4b80a 100644 (file)
@@ -53,7 +53,7 @@ Q_OBJECT public:
     void slotAddTextClipFile(const QString titleName, const QString imagePath, const QString xml, const QString group, const QString &groupId);
     void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const QString &groupId);
     void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, const int softness, const QString group, const QString &groupId);
-    DocClipBase *getClipById(const QString &clipId);
+    DocClipBase *getClipById(QString clipId);
     void slotDeleteClip(const QString & clipId);
     void setThumbsProgress(const QString &message, int progress);
     void checkAudioThumbs();
index ac804748f48ed61b09c8a95cc1fdaa5f171e2b99..087477d9ea9bd3959da19d311905e00bef0a8787 100644 (file)
@@ -1136,7 +1136,7 @@ void CustomTrackView::dropEvent(QDropEvent * event) {
                 m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_scene->m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML());
             }
             info.track = m_scene->m_tracksList.count() - item->track();
-            m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer());
+            m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer(item->track()));
             item->setSelected(true);
         }
         m_document->setModified(true);
@@ -1277,11 +1277,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
         if (m_selectionGroup == NULL) {
             // we are moving one clip, easy
             if (m_dragItem->type() == AVWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
-                bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())));
+                ClipItem *item = static_cast <ClipItem *>(m_dragItem);
+                bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())), item->baseClip()->producer(info.track));
                 if (success) {
                     MoveClipCommand *command = new MoveClipCommand(this, m_dragItemInfo, info, false);
                     m_commandStack->push(command);
-                    ClipItem *item = static_cast <ClipItem *>(m_dragItem);
                     if (item->baseClip()->isTransparent()) {
                         // Also move automatic transition
                         Transition *tr = getTransitionItemAt((int) m_dragItemInfo.startPos.frames(m_document->fps()) + 1, m_dragItemInfo.track);
@@ -1347,7 +1347,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
                         new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, clip->effectList(), false, false, moveClips);
                         info.track = m_scene->m_tracksList.count() - info.track;
-                        m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer());
+                        m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer(info.track));
                     } else {
                         Transition *tr = static_cast <Transition*>(item);
                         ItemInfo transitionInfo = tr->info();
@@ -1587,7 +1587,7 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i
     baseclip->addReference();
     m_document->updateClip(baseclip->getId());
     info.track = m_scene->m_tracksList.count() - info.track;
-    m_document->renderer()->mltInsertClip(info, xml, baseclip->producer());
+    m_document->renderer()->mltInsertClip(info, xml, baseclip->producer(info.track));
     for (int i = 0; i < item->effectsCount(); i++) {
         m_document->renderer()->mltAddEffect(info.track, info.startPos, item->getEffectArgs(item->effectAt(i)), false);
     }
@@ -1653,7 +1653,7 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) {
     }
     //kDebug() << "----------------  Move CLIP FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << startPos.y() << " TO " << endPos.y();
 
-    bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()));
+    bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()), item->baseClip()->producer(end.track));
     if (success) {
         item->setPos((int) end.startPos.frames(m_document->fps()), (int)(end.track * m_tracksHeight + 1));
         if (item->baseClip()->isTransparent()) {
index 40560034ee33095d96cc7a25f6e046a23ea123c0..bf26e183182901bf4cf9c6fd22b0092d980036d7 100644 (file)
@@ -23,7 +23,7 @@
 #include "clipmanager.h"
 
 DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id):
-        m_id(id), m_description(QString()), m_refcount(0), m_audioThumbCreated(false), m_duration(GenTime()), m_thumbProd(NULL), m_audioTimer(NULL), m_clipProducer(NULL), m_properties(QMap <QString, QString> ()), audioFrameChache(QMap<int, QMap<int, QByteArray> > ()) {
+        m_id(id), m_description(QString()), m_refcount(0), m_audioThumbCreated(false), m_duration(GenTime()), m_thumbProd(NULL), m_audioTimer(NULL), m_properties(QMap <QString, QString> ()), audioFrameChache(QMap<int, QMap<int, QByteArray> > ()), m_baseTrackProducers(QList <Mlt::Producer *>())  {
     int type = xml.attribute("type").toInt();
     m_clipType = (CLIPTYPE) type;
     m_name = xml.attribute("name");
@@ -64,7 +64,7 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin
 
 DocClipBase::~DocClipBase() {
     if (m_thumbProd) delete m_thumbProd;
-    if (m_clipProducer) delete m_clipProducer;
+    qDeleteAll(m_baseTrackProducers);
 }
 
 void DocClipBase::slotCreateAudioTimer() {
@@ -120,6 +120,7 @@ const CLIPTYPE & DocClipBase::clipType() const {
 
 void DocClipBase::setClipType(CLIPTYPE type) {
     m_clipType = type;
+
     m_properties.insert("type", QString::number((int) type));
     if (m_thumbProd && m_audioTimer == NULL && (m_clipType == AV || m_clipType == AUDIO))
         slotCreateAudioTimer();
@@ -366,17 +367,72 @@ QString DocClipBase::markerComment(GenTime t) {
 
 void DocClipBase::setProducer(Mlt::Producer *producer) {
     if (producer == NULL) return;
-    m_clipProducer = producer;
-    m_clipProducer->set("transparency", m_properties.value("transparency").toInt());
-    if (m_thumbProd) m_thumbProd->setProducer(producer);
+    QString id = producer->get("id");
+    kDebug() << "// SET PRODUCER: " << id;
+    if (id.contains('_')) {
+        // this is a subtrack producer, insert it at correct place
+        int pos = id.section('_', 1, 1).toInt();
+        kDebug() << "// POS = " << pos << ", MAX: " << m_baseTrackProducers.count();
+        if (pos >= m_baseTrackProducers.count()) {
+            while (m_baseTrackProducers.count() - 1 < pos) {
+                m_baseTrackProducers.append(NULL);
+            }
+        }
+        kDebug() << "// POS = " << pos << ", NEW MAX: " << m_baseTrackProducers.count();
+        if (m_baseTrackProducers.at(pos) == NULL) m_baseTrackProducers[pos] = producer;
+    } else m_baseTrackProducers.append(producer);
+    //m_clipProducer = producer;
+    //m_clipProducer->set("transparency", m_properties.value("transparency").toInt());
+    if (m_thumbProd && !m_thumbProd->hasProducer()) m_thumbProd->setProducer(producer);
+}
+
+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);
+        return NULL;
+    }
+    if (track >= m_baseTrackProducers.count()) {
+        while (m_baseTrackProducers.count() - 1 < track) {
+            m_baseTrackProducers.append(NULL);
+        }
+    }
+    if (m_baseTrackProducers.at(track) == NULL) {
+        int i;
+        for (i = 0; i < m_baseTrackProducers.count(); i++)
+            if (m_baseTrackProducers.at(i) != NULL) break;
+        if (i >= m_baseTrackProducers.count()) return NULL;
+        m_baseTrackProducers[track] = new Mlt::Producer(*m_baseTrackProducers.at(i)->profile(), m_baseTrackProducers.at(i)->get("resource"));
+        if (m_properties.contains("force_aspect_ratio")) m_baseTrackProducers[track]->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+        if (m_properties.contains("threads")) m_baseTrackProducers[track]->set("threads", m_properties.value("threads").toInt());
+        if (m_properties.contains("video_index")) m_baseTrackProducers[track]->set("video_index", m_properties.value("video_index").toInt());
+        if (m_properties.contains("audio_index")) m_baseTrackProducers[track]->set("audio_index", m_properties.value("audio_index").toInt());
+        char *tmp = (char *) qstrdup(QString(getId() + '_' + QString::number(track)).toUtf8().data());
+        m_baseTrackProducers[track]->set("id", tmp);
+        delete[] tmp;
+    }
+    return m_baseTrackProducers.at(track);
+}
+
+void DocClipBase::setProducerProperty(const char *name, int data) {
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i) != NULL)
+            m_baseTrackProducers[i]->set(name, data);
+    }
 }
 
-Mlt::Producer *DocClipBase::producer() {
-    return m_clipProducer;
+void DocClipBase::setProducerProperty(const char *name, const char *data) {
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i) != NULL)
+            m_baseTrackProducers[i]->set(name, data);
+    }
 }
 
 void DocClipBase::slotRefreshProducer() {
-    if (m_clipProducer == NULL) return;
+    if (m_baseTrackProducers.count() == 0) return;
     kDebug() << "////////////   REFRESH CLIP !!!!!!!!!!!!!!!!";
     if (m_clipType == SLIDESHOW) {
         /*char *tmp = (char *) qstrdup(getProperty("resource").toUtf8().data());
@@ -385,12 +441,12 @@ void DocClipBase::slotRefreshProducer() {
         delete m_clipProducer;
         m_clipProducer = new Mlt::Producer(producer.get_producer());
         if (!getProperty("out").isEmpty()) m_clipProducer->set_in_and_out(getProperty("in").toInt(), getProperty("out").toInt());*/
-        m_clipProducer->set("ttl", getProperty("ttl").toInt());
+        setProducerProperty("ttl", getProperty("ttl").toInt());
         //m_clipProducer->set("id", getProperty("id"));
         if (getProperty("fade") == "1") {
             // we want a fade filter effect
             kDebug() << "////////////   FADE WANTED";
-            Mlt::Service clipService(m_clipProducer->get_service());
+            Mlt::Service clipService(m_baseTrackProducers.at(0)->get_service());
             int ct = 0;
             Mlt::Filter *filter = clipService.filter(ct);
             while (filter) {
@@ -414,7 +470,7 @@ void DocClipBase::slotRefreshProducer() {
                 }
             } else {
                 // filter does not exist, create it...
-                Mlt::Filter *filter = new Mlt::Filter(*(m_clipProducer->profile()), "luma");
+                Mlt::Filter *filter = new Mlt::Filter(*(m_baseTrackProducers.at(0)->profile()), "luma");
                 filter->set("period", getProperty("ttl").toInt() - 1);
                 filter->set("luma.out", getProperty("luma_duration").toInt());
                 QString resource = getProperty("luma_file");
@@ -429,7 +485,7 @@ void DocClipBase::slotRefreshProducer() {
             }
         } else {
             kDebug() << "////////////   FADE NOT WANTED!!!";
-            Mlt::Service clipService(m_clipProducer->get_service());
+            Mlt::Service clipService(m_baseTrackProducers.at(0)->get_service());
             int ct = 0;
             Mlt::Filter *filter = clipService.filter(0);
             while (filter) {
@@ -465,33 +521,33 @@ void DocClipBase::setProperty(const QString &key, const QString &value) {
     m_properties.insert(key, value);
     if (key == "resource") m_thumbProd->updateClipUrl(KUrl(value));
     else if (key == "out") setDuration(GenTime(value.toInt(), KdenliveSettings::project_fps()));
-    else if (key == "transparency") m_clipProducer->set("transparency", value.toInt());
+    //else if (key == "transparency") m_clipProducer->set("transparency", value.toInt());
     else if (key == "colour") {
         char *tmp = (char *) qstrdup(value.toUtf8().data());
-        m_clipProducer->set("colour", tmp);
+        setProducerProperty("colour", tmp);
         delete[] tmp;
     } else if (key == "xmldata") {
-        m_clipProducer->set("force_reload", 1);
+        setProducerProperty("force_reload", 1);
     } else if (key == "force_aspect_ratio") {
         if (value.isEmpty()) {
             m_properties.remove("force_aspect_ratio");
-            m_clipProducer->set("force_aspect_ratio", 0);
-        } else m_clipProducer->set("force_aspect_ratio", value.toDouble());
+            setProducerProperty("force_aspect_ratio", 0);
+        } else setProducerProperty("force_aspect_ratio", value.toDouble());
     } else if (key == "threads") {
         if (value.isEmpty()) {
             m_properties.remove("threads");
-            m_clipProducer->set("threads", 1);
-        } else m_clipProducer->set("threads", value.toInt());
+            setProducerProperty("threads", 1);
+        } else setProducerProperty("threads", value.toInt());
     } else if (key == "video_index") {
         if (value.isEmpty()) {
             m_properties.remove("video_index");
-            m_clipProducer->set("video_index", m_properties.value("default_video").toInt());
-        } else m_clipProducer->set("video_index", value.toInt());
+            setProducerProperty("video_index", m_properties.value("default_video").toInt());
+        } else setProducerProperty("video_index", value.toInt());
     } else if (key == "audio_index") {
         if (value.isEmpty()) {
             m_properties.remove("audio_index");
-            m_clipProducer->set("audio_index", m_properties.value("default_audio").toInt());
-        } else m_clipProducer->set("audio_index", value.toInt());
+            setProducerProperty("audio_index", m_properties.value("default_audio").toInt());
+        } else setProducerProperty("audio_index", value.toInt());
     }
 }
 
index 893b325f8274be124f96cb16299deca34f353297..cc427b0d96076ae230b92454fce6d55568516b5d 100644 (file)
@@ -111,7 +111,7 @@ Q_OBJECT public:
     }
 
     void setProducer(Mlt::Producer *producer);
-    Mlt::Producer *producer();
+    Mlt::Producer *producer(int track = -1);
 
     /*virtual DocClipAVFile *toDocClipAVFile() {
     return 0;
@@ -197,7 +197,7 @@ private:   // Private attributes
     /** The number of times this clip is used in the project - the number of references to this clip
      * that exist. */
     uint m_refcount;
-    Mlt::Producer *m_clipProducer;
+    QList <Mlt::Producer *> m_baseTrackProducers;
     CLIPTYPE m_clipType;
 
     /** A list of snap markers; these markers are added to a clips snap-to points, and are displayed as necessary. */
@@ -219,6 +219,8 @@ 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);
 
 public slots:
     void updateAudioThumbnail(QMap<int, QMap<int, QByteArray> > data);
index 59d34d7668ff3bfcdddd382117f74b826a01de91..db4b3ef395d7d0a8032b201b9d864d44cdb958d0 100644 (file)
@@ -56,10 +56,10 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                 m_zoom = infoXml.attribute("zoom", "7").toInt();
                 setProfilePath(profilePath);
                 double version = infoXml.attribute("version").toDouble();
-                if (version < 0.7) convertDocument(version);
+                if (version < 0.8) convertDocument(version);
                 else {
                     //delete all mlt producers and instead, use Kdenlive saved producers
-                    QDomNodeList prods = m_document.elementsByTagName("producer");
+                    /*QDomNodeList prods = m_document.elementsByTagName("producer");
                     int maxprod = prods.count();
                     int pos = 0;
                     for (int i = 0; i < maxprod; i++) {
@@ -68,19 +68,22 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                         if (prodId == "black" || prodId.startsWith("slowmotion"))
                             pos++;
                         else westley.removeChild(m);
-                    }
-                    prods = m_document.elementsByTagName("kdenlive_producer");
+                    }*/
+                    /*prods = m_document.elementsByTagName("kdenlive_producer");
                     maxprod = prods.count();
                     for (int i = 0; i < maxprod; i++) {
                         prods.at(0).toElement().setTagName("producer");
                         westley.insertBefore(prods.at(0), QDomNode());
-                    }
+                    }*/
                 }
                 QDomElement e;
                 QDomNodeList producers = m_document.elementsByTagName("producer");
+                QDomNodeList infoproducers = m_document.elementsByTagName("kdenlive_producer");
                 const int max = producers.count();
+                const int infomax = infoproducers.count();
+
                 if (max > 0) {
-                    m_documentLoadingStep = 100.0 / (max + m_document.elementsByTagName("entry").count());
+                    m_documentLoadingStep = 100.0 / (max + infomax + m_document.elementsByTagName("entry").count());
                     parent->slotGotProgressInfo(i18n("Loading project clips"), (int) m_documentLoadingProgress);
                 }
 
@@ -89,11 +92,27 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                     if (m_documentLoadingStep > 0) {
                         m_documentLoadingProgress += m_documentLoadingStep;
                         parent->slotGotProgressInfo(QString(), (int) m_documentLoadingProgress);
-                        qApp->processEvents();
+                        //qApp->processEvents();
                     }
                     QString prodId = e.attribute("id");
                     if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion")/*&& prodId.toInt() > 0*/) {
-                        addClip(e, prodId);
+                        // addClip(e, prodId, false);
+                        kDebug() << "// PROD: " << prodId;
+                    }
+                }
+
+                for (int i = 0; i < infomax; i++) {
+                    e = infoproducers.item(i).cloneNode().toElement();
+                    if (m_documentLoadingStep > 0) {
+                        m_documentLoadingProgress += m_documentLoadingStep;
+                        parent->slotGotProgressInfo(QString(), (int) m_documentLoadingProgress);
+                        //qApp->processEvents();
+                    }
+                    QString prodId = e.attribute("id");
+                    if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion")) {
+                        e.setTagName("producer");
+                        addClipInfo(e, prodId);
+                        kDebug() << "// NLIVE PROD: " << prodId;
                     }
                 }
 
@@ -254,7 +273,9 @@ void KdenliveDoc::slotAutoSave() {
             kDebug() << "ERROR; CANNOT CREATE AUTOSAVE FILE";
         }
         kDebug() << "// AUTOSAVE FILE: " << m_autosave->fileName();
-        m_render->saveSceneList(m_autosave->fileName(), documentInfoXml());
+        QDomDocument doc;
+        doc.setContent(m_render->sceneList());
+        saveSceneList(m_autosave->fileName(), doc);
     }
 }
 
@@ -268,6 +289,10 @@ int KdenliveDoc::zoom() const {
 
 void KdenliveDoc::convertDocument(double version) {
     // Opening a old Kdenlive document
+    if (version == 0.7) {
+        // TODO: convert 0.7 files to the new document format.
+        return;
+    }
     QDomNode westley = m_document.elementsByTagName("westley").at(1);
     QDomNode tractor = m_document.elementsByTagName("tractor").at(0);
     QDomNode kdenlivedoc = m_document.elementsByTagName("kdenlivedoc").at(0);
@@ -533,6 +558,48 @@ QString KdenliveDoc::colorToString(const QColor& c) {
     return ret;
 }
 
+void KdenliveDoc::saveSceneList(const QString &path, QDomDocument sceneList) {
+    QDomNode wes = sceneList.elementsByTagName("westley").at(0);
+
+    QDomElement addedXml = sceneList.createElement("kdenlivedoc");
+    QDomElement markers = sceneList.createElement("markers");
+    addedXml.setAttribute("version", "0.8");
+    addedXml.setAttribute("profile", profilePath());
+    addedXml.setAttribute("position", m_render->seekPosition().frames(m_fps));
+    addedXml.setAttribute("zoom", m_zoom);
+
+    QDomElement e;
+    QList <DocClipBase*> list = m_clipManager->documentClipList();
+    for (int i = 0; i < list.count(); i++) {
+        e = list.at(i)->toXML();
+        e.setTagName("kdenlive_producer");
+        addedXml.appendChild(sceneList.importNode(e, true));
+        QList < CommentedTime > marks = list.at(i)->commentedSnapMarkers();
+        for (int j = 0; j < marks.count(); j++) {
+            QDomElement marker = sceneList.createElement("marker");
+            marker.setAttribute("time", marks.at(j).time().ms() / 1000);
+            marker.setAttribute("comment", marks.at(j).comment());
+            marker.setAttribute("id", e.attribute("id"));
+            markers.appendChild(marker);
+        }
+    }
+    addedXml.appendChild(markers);
+    if (!m_guidesXml.isNull()) addedXml.appendChild(sceneList.importNode(m_guidesXml, true));
+
+    wes.appendChild(addedXml);
+    //wes.appendChild(doc.importNode(kdenliveData, true));
+
+    QFile file(path);
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+        kWarning() << "//////  ERROR writing to file: " << path;
+        return;
+    }
+    QTextStream out(&file);
+    out << sceneList.toString();
+    file.close();
+
+}
+
 QDomElement KdenliveDoc::documentInfoXml() {
     QDomDocument doc;
     QDomElement e;
@@ -620,7 +687,7 @@ void KdenliveDoc::setRenderer(Render *render) {
     if (m_render) return;
     m_render = render;
     emit progressInfo(i18n("Loading playlist..."), 0);
-    qApp->processEvents();
+    //qApp->processEvents();
     if (m_render) {
         m_render->setSceneList(m_document.toString(), m_startPos);
         checkProjectClips();
@@ -632,12 +699,16 @@ void KdenliveDoc::checkProjectClips() {
     if (m_render == NULL) return;
     QList <Mlt::Producer *> prods = m_render->producersList();
     QString id ;
+    QString prodId ;
+    QString prodTrack ;
     for (int i = 0; i < prods.count(); i++) {
         id = prods.at(i)->get("id");
-        DocClipBase *clip = m_clipManager->getClipById(id);
-        if (clip && clip->producer() == NULL) {
-            clip->setProducer(prods.at(i));
-        }
+        prodId = id.section('_', 0, 0);
+        prodTrack = id.section('_', 1, 1);
+        kDebug() << "CHECK PRO CLIP, ID: " << id;
+        DocClipBase *clip = m_clipManager->getClipById(prodId);
+        if (clip) clip->setProducer(prods.at(i));
+        kDebug() << "CHECK PRO CLIP, ID: " << id << " DONE";
         if (clip && clip->clipType() == TEXT && !QFile::exists(clip->fileURL().path())) {
             // regenerate text clip image if required
             kDebug() << "// TITLE: " << clip->getProperty("titlename") << " Preview file: " << clip->getProperty("resource") << " DOES NOT EXIST";
@@ -787,11 +858,35 @@ QString KdenliveDoc::description() const {
         return m_url.fileName() + " / " + m_profile.description;
 }
 
-void KdenliveDoc::addClip(const QDomElement &elem, const QString &clipId) {
-    DocClipBase *clip = new DocClipBase(m_clipManager, elem, clipId);
-    kDebug() << "/////////  DOCUM, CREATING NEW CLIP, ID:" << clipId << ", PAR ID:" << elem.attribute("groupid");
-    m_clipManager->addClip(clip);
-    emit addProjectClip(clip);
+void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) {
+    const QString producerId = clipId.section('_', 0, 0);
+    int subtrack = clipId.section('_', 1, 1).toInt();
+    DocClipBase *clip = m_clipManager->getClipById(producerId);
+    if (clip == NULL) {
+        elem.setAttribute("id", producerId);
+        clip = new DocClipBase(m_clipManager, elem, producerId);
+        m_clipManager->addClip(clip);
+    }
+    if (createClipItem) emit addProjectClip(clip);
+}
+
+void KdenliveDoc::addClipInfo(QDomElement elem, QString clipId) {
+    DocClipBase *clip = m_clipManager->getClipById(clipId);
+    if (clip == NULL) {
+        addClip(elem, clipId);
+    } else {
+        QMap <QString, QString> properties;
+        QDomNamedNodeMap attributes = elem.attributes();
+        QString attrname;
+        for (unsigned int i = 0; i < attributes.count(); i++) {
+            attrname = attributes.item(i).nodeName();
+            if (attrname != "resource")
+                properties.insert(attrname, attributes.item(i).nodeValue());
+            kDebug() << attrname << " = " << attributes.item(i).nodeValue();
+        }
+        clip->setProperties(properties);
+        emit addProjectClip(clip);
+    }
 }
 
 void KdenliveDoc::addFolder(const QString foldername, const QString &clipId, bool edit) {
index 5a9d3990a3f934ae039f58b17dacbb0f02e28df4..ce1ffafd401f465505293ec085c324e13aa95f8e 100644 (file)
@@ -66,7 +66,8 @@ Q_OBJECT public:
     QDomElement m_guidesXml;
     QDomElement guidesXml() const;
     ClipManager *clipManager();
-    void addClip(const QDomElement &elem, const QString &clipId);
+    void addClip(QDomElement elem, QString clipId, bool createClipItem = true);
+    void addClipInfo(QDomElement elem, QString clipId);
     void addFolder(const QString foldername, const QString &clipId, bool edit);
     void deleteFolder(const QString foldername, const QString &clipId);
     void slotAddClipFile(const KUrl url, const QString group, const QString &groupId = QString());
@@ -104,6 +105,7 @@ Q_OBJECT public:
     int zoom() const;
     const double dar();
     double projectDuration() const;
+    void saveSceneList(const QString &path, QDomDocument sceneList);
 
 private:
     KUrl m_url;
index 7e2ed60c1148eac302c0e9719be16fb355115f91..387906a16dbcd5d482a6d0b980d4bf95dfed0ecd 100644 (file)
@@ -934,7 +934,8 @@ void MainWindow::closeCurrentDocument() {
 }
 
 void MainWindow::saveFileAs(const QString &outputFileName) {
-    m_projectMonitor->saveSceneList(outputFileName, m_activeDocument->documentInfoXml());
+    QDomDocument currentSceneList = m_projectMonitor->sceneList();
+    m_activeDocument->saveSceneList(outputFileName, currentSceneList);
     m_activeDocument->setUrl(KUrl(outputFileName));
     if (m_activeDocument->m_autosave == NULL) {
         m_activeDocument->m_autosave = new KAutoSaveFile(KUrl(outputFileName), this);
index 9ad543b5f2a1a67ff2dabfb96678d352e1cd00fa..95d5ec2213b76c93eb5a440f596d9abfd8a806a7 100644 (file)
@@ -557,6 +557,13 @@ void Monitor::saveSceneList(QString path, QDomElement info) {
     render->saveSceneList(path, info);
 }
 
+QDomDocument Monitor::sceneList() {
+    if (render == NULL) return QDomDocument();
+    QDomDocument doc;
+    doc.setContent(render->sceneList());
+    return doc;
+}
+
 MonitorRefresh::MonitorRefresh(QWidget* parent): QWidget(parent), m_renderer(NULL) {
     setAttribute(Qt::WA_PaintOnScreen);
     setAttribute(Qt::WA_OpaquePaintEvent); //setAttribute(Qt::WA_NoSystemBackground);
index 4d97a4b7b51a211f9ee314a662f33d04cbf2f8a9..6e989dc96af03e7c6faa70274e705f6c1f4d6a81 100644 (file)
@@ -56,6 +56,7 @@ public:
     bool isActive() const;
     void pause();
     void setupMenu(QMenu *goMenu);
+    QDomDocument sceneList();
 
 protected:
     virtual void mousePressEvent(QMouseEvent * event);
index a720b9da3321853867ab2723d73dbe62e153bef2..d7de11cce011aa95489109d525a23744ae22554f 100644 (file)
@@ -116,7 +116,7 @@ void ProjectListView::mouseDoubleClickEvent(QMouseEvent * event) {
         if ((columnAt(event->pos().x()) == 1)) QTreeWidget::mouseDoubleClickEvent(event);
     } else {
         if ((columnAt(event->pos().x()) == 2)) QTreeWidget::mouseDoubleClickEvent(event);
-       else emit showProperties(item->referencedClip());
+        else emit showProperties(item->referencedClip());
     }
 }
 
index 36df5e29c2d2032c37126ac16c83ddf5cd4cbce9..e0ce8c473dcc3e725db77668dbe7d0926fb98225 100644 (file)
@@ -1943,12 +1943,12 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
     return true;
 }
 
-bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd) {
-    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps));
+bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod) {
+    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod);
 }
 
 
-bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd) {
+bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod) {
     m_isBlocked = true;
 
     m_mltConsumer->set("refresh", 0);
@@ -1994,7 +1994,23 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
             trackPlaylist.consolidate_blanks(0);
             destTrackPlaylist.consolidate_blanks(1);
-            int newIndex = destTrackPlaylist.insert_at(moveEnd, clipProducer, 1);
+            Mlt::Producer *clip = prod->cut(clipProducer.get_in(), clipProducer.get_out());
+
+            // move all effects to the correct producer
+            Mlt::Service clipService(clipProducer.get_service());
+            Mlt::Service newClipService(clip->get_service());
+
+            int ct = 0;
+            Mlt::Filter *filter = clipService.filter(ct);
+            while (filter) {
+                if (filter->get("kdenlive_ix") != 0) {
+                    clipService.detach(*filter);
+                    newClipService.attach(*filter);
+                } else ct++;
+                filter = clipService.filter(ct);
+            }
+
+            int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
             destTrackPlaylist.consolidate_blanks(0);
             /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
                 kDebug() << "//////// moving clip transparency";
index 45688b92cf02b858db24564dbabd45973e3f9d8a..1298b44153b9718b8525bafacd33c49f35e9419a 100644 (file)
@@ -153,8 +153,8 @@ Q_OBJECT public:
     void mltCutClip(int track, GenTime position);
     bool mltResizeClipEnd(ItemInfo info, GenTime clipDuration);
     bool mltResizeClipStart(ItemInfo info, GenTime diff);
-    bool mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart);
-    bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart);
+    bool mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart, Mlt::Producer *prod);
+    bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart, Mlt::Producer *prod);
     bool mltRemoveClip(int track, GenTime position);
     bool mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh = true);
     bool mltAddEffect(int track, GenTime position, QHash <QString, QString> args, bool doRefresh = true);
index de5eb9bd14116a40325a30e189719aabea33bf77..431876109fe650088a636beea15394131b72aa66 100644 (file)
@@ -201,7 +201,7 @@ void TrackView::parseDocument(QDomDocument doc) {
             ItemInfo transitionInfo;
             QString transitionId;
             if (mlt_service == "composite") {
-                kDebug() << "//////////\n\nADDING COMPO TRANS\n\n " << mlt_geometry << "\n\n//////////";
+                // When adding composite transition, check if it is a wipe transition
                 if (mlt_geometry == "0%,0%:100%x100%") transitionId = "alphatransparency";
                 else if (mlt_geometry.count(';') == 1) {
                     mlt_geometry.remove(QChar('%'), Qt::CaseInsensitive);
@@ -379,7 +379,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) {
                 hasSpeedAttribute = true;
                 id = idString.section(":", 1, 1);
                 speed = idString.section(":", 2, 2).toDouble();
-            }
+            } else id = id.section('_', 0, 0);
             DocClipBase *clip = m_doc->clipManager()->getClipById(id);
             if (clip != NULL) {
                 int out = elem.attribute("out").toInt();