]> git.sesse.net Git - kdenlive/commitdiff
Add / remove track now seems to work, still a few crashes if project monitor was...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 2 Dec 2008 18:43:48 +0000 (18:43 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 2 Dec 2008 18:43:48 +0000 (18:43 +0000)
svn path=/branches/KDE4/; revision=2747

src/customtrackview.cpp
src/customtrackview.h
src/docclipbase.cpp
src/moveclipcommand.cpp
src/moveclipcommand.h
src/renderer.cpp
src/renderer.h

index 393b97198e1420408a0e126e9ec71f8d676c1834..9259a57309387f3b45fca2b2f9dedc50f927e0da 100644 (file)
@@ -796,7 +796,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) {
                     endInfo.startPos = d.startPos();
                     endInfo.endPos = m_dragItem->endPos() + (endInfo.startPos - startInfo.startPos);
                     endInfo.track = m_dragItem->track();
-                    MoveClipCommand *command = new MoveClipCommand(this, startInfo, endInfo, false, true);
+                    MoveClipCommand *command = new MoveClipCommand(this, startInfo, endInfo, true);
                     m_commandStack->push(command);
                 } else {
                     //TODO: move transition
@@ -1346,8 +1346,10 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) {
             if (item->type() == AVWIDGET) {
                 ClipItem *clip = static_cast <ClipItem *>(item);
                 // We add a move clip command so that we get the correct producer for new track number
-                /*if (clip->clipType() == AV || clip->clipType() == AUDIO)
-                    moveClip(clipinfo, clipinfo, true);*/
+                if (clip->clipType() == AV || clip->clipType() == AUDIO) {
+                    m_document->renderer()->mltUpdateClipProducer((int)(m_scene->m_tracksList.count() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), clip->baseClip()->producer(clipinfo.track));
+                    kDebug() << "// UPDATING CLIP TO TRACK PROD: " << clipinfo.track;
+                }
             } else if (item->type() == TRANSITIONWIDGET) {
                 Transition *tr = static_cast <Transition *>(item);
                 int track = tr->transitionEndTrack();
@@ -1402,8 +1404,8 @@ void CustomTrackView::removeTrack(int ix) {
             ItemInfo clipinfo = clip->info();
             kDebug() << "// CLIP TRK IS: " << clipinfo.track;
             // We add a move clip command so that we get the correct producer for new track number
-            /*if (clip->clipType() == AV || clip->clipType() == AUDIO)
-            moveClip(clipinfo, clipinfo, true);*/
+            if (clip->clipType() == AV || clip->clipType() == AUDIO)
+                m_document->renderer()->mltUpdateClipProducer((int)(m_scene->m_tracksList.count() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), clip->baseClip()->producer(clipinfo.track));
         } else if (children.at(i)->type() == TRANSITIONWIDGET) {
             Transition *tr = static_cast <Transition *>(children.at(i));
             tr->updateItem();
@@ -1625,7 +1627,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     }
                 } else {
                     // undo last move and emit error message
-                    MoveClipCommand *command = new MoveClipCommand(this, info, m_dragItemInfo, false, true);
+                    MoveClipCommand *command = new MoveClipCommand(this, info, m_dragItemInfo, true);
                     m_commandStack->push(command);
                     emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(m_dragItemInfo.startPos.seconds(), 'g', 2)), ErrorMessage);
                 }
@@ -1978,7 +1980,7 @@ Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) {
     return getTransitionItemAt(framepos, track);
 }
 
-void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end, bool forceProducer) {
+void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) {
     ClipItem *item = getClipItemAt((int) start.startPos.frames(m_document->fps()) + 1, start.track);
     if (!item) {
         emit displayMessage(i18n("Cannot move clip at time: %1s on track %2", QString::number(start.startPos.seconds(), 'g', 2), start.track), ErrorMessage);
@@ -1987,7 +1989,7 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end, bool fo
     }
     //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()), item->baseClip()->producer(end.track), forceProducer);
+    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()) {
@@ -2715,6 +2717,7 @@ void CustomTrackView::slotInsertTrack(int ix) {
             info.isBlind = false;
         }
         addTimelineTrack(ix, info);
+        m_document->setModified(true);
         /*AddTrackCommand* command = new AddTrackCommand(this, ix, info, true, true);
         m_commandStack->push(command);*/
     }
@@ -2726,6 +2729,7 @@ void CustomTrackView::slotDeleteTrack(int ix) {
     if (ok) {
         TrackInfo info = m_scene->m_tracksList.at(m_scene->m_tracksList.count() - ix);
         deleteTimelineTrack(ix, info);
+        m_document->setModified(true);
         /*AddTrackCommand* command = new AddTrackCommand(this, ix, info, false, true);
         m_commandStack->push(command);*/
     }
@@ -2757,7 +2761,7 @@ void CustomTrackView::deleteTimelineTrack(int ix, TrackInfo trackinfo) {
     for (int i = 0; i < selection.count(); i++) {
         if (selection.at(i)->type() == AVWIDGET) {
             ClipItem *item =  static_cast <ClipItem *>(selection.at(i));
-            new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, false, deleteTrack);
+            new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, true, deleteTrack);
             m_scene->removeItem(item);
             delete item;
             item = NULL;
index a07d4b8b8297ae583e6b7c8cf8587681a723a910..a95a15b58a3e92c3c4e4b8599072f622ff3e3360 100644 (file)
@@ -52,7 +52,7 @@ public:
     void removeTrack(int ix);
     int cursorPos();
     void checkAutoScroll();
-    void moveClip(const ItemInfo start, const ItemInfo end, bool forceProducer);
+    void moveClip(const ItemInfo start, const ItemInfo end);
     /** move transition, startPos = (old start, old end), endPos = (new start, new end) */
     void moveTransition(const ItemInfo start, const ItemInfo end);
     void resizeClip(const ItemInfo start, const ItemInfo end);
index af567b60daca8fc2431b40fda9ce1764d27a7878..5dc1b0f4357b04d86acef570877c027826c630b0 100644 (file)
@@ -251,7 +251,7 @@ const QPixmap & DocClipBase::thumbnail() const {
 }
 
 void DocClipBase::updateAudioThumbnail(QMap<int, QMap<int, QByteArray> > data) {
-    kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************";
+    //kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************";
     audioFrameChache = data;
     m_audioThumbCreated = true;
     emit gotAudioData();
@@ -371,25 +371,28 @@ QString DocClipBase::markerComment(GenTime t) {
 void DocClipBase::setProducer(Mlt::Producer *producer) {
     if (producer == NULL) return;
     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);
+    } else {
+        if (m_baseTrackProducers.isEmpty()) m_baseTrackProducers.append(producer);
+        else if (m_baseTrackProducers.at(0) == NULL) m_baseTrackProducers[0] = 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) {
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i)) kDebug() << "// PROD: " << i << ", ID: " << m_baseTrackProducers.at(i)->get("id");
+    }
     if (track == -1 || (m_clipType != AUDIO && m_clipType != AV)) {
         if (m_baseTrackProducers.count() == 0) return NULL;
         int i;
index 1cc459bb6384df1ec5039a3365fcd2de5b46f93d..5d9f91c796e45e6d2c2cde9a06b0fa3f32b92a3d 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "moveclipcommand.h"
 #include "customtrackview.h"
-MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool forceProducer, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_startPos(start), m_endPos(end), m_forceProducer(forceProducer), m_doIt(doIt) {
+MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_startPos(start), m_endPos(end), m_doIt(doIt) {
     setText(i18n("Move clip"));
 }
 
@@ -30,13 +30,13 @@ MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo start, co
 void MoveClipCommand::undo() {
 // kDebug()<<"----  undoing action";
     m_doIt = true;
-    m_view->moveClip(m_endPos, m_startPos, m_forceProducer);
+    m_view->moveClip(m_endPos, m_startPos);
 }
 // virtual
 void MoveClipCommand::redo() {
     kDebug() << "----  redoing action";
     if (m_doIt)
-        m_view->moveClip(m_startPos, m_endPos, m_forceProducer);
+        m_view->moveClip(m_startPos, m_endPos);
     m_doIt = true;
 }
 
index 6c785a8c2dedd965e3d3469bd0b217292361ee7b..b1803ca4f3e12e71de8c7044b06a56306a742e81 100644 (file)
@@ -32,7 +32,7 @@ class CustomTrackView;
 
 class MoveClipCommand : public QUndoCommand {
 public:
-    MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool forceProducer, bool doIt, QUndoCommand * parent = 0);
+    MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt, QUndoCommand * parent = 0);
     virtual void undo();
     virtual void redo();
 
@@ -41,7 +41,6 @@ private:
     const ItemInfo m_startPos;
     const ItemInfo m_endPos;
     bool m_doIt;
-    bool m_forceProducer;
 };
 
 #endif
index bcd0d59539616c8360af84c5c200780f2b52b89c..37011c5ee64e080505fd6ea60086be5a97539baa 100644 (file)
@@ -2099,12 +2099,52 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
     return true;
 }
 
-bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod, bool forceProducer) {
-    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod, forceProducer);
+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, Mlt::Producer *prod, bool forceProducer) {
+void Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod) {
+    kDebug() << "NEW PROD ID: " << prod->get("id");
+    m_mltConsumer->set("refresh", 0);
+    kDebug() << "// TRYING TO UPDATE CLIP at: " << pos << ", TK: " << track;
+    mlt_service_lock(m_mltConsumer->get_service());
+    Mlt::Service service(m_mltProducer->parent().get_service());
+    if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM";
+
+    Mlt::Tractor tractor(service);
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+    int clipIndex = trackPlaylist.get_clip_index_at(pos + 1);
+    Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
+    if (clipProducer.is_blank()) {
+        kDebug() << "// ERROR UPDATING CLIP PROD";
+        mlt_service_unlock(m_mltConsumer->get_service());
+        m_isBlocked = false;
+        return;
+    }
+    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);
+    }
+
+    trackPlaylist.insert_at(pos, clip, 1);
+    mlt_service_unlock(m_mltConsumer->get_service());
+    m_isBlocked = false;
+}
+
+bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod) {
     m_isBlocked = true;
 
     m_mltConsumer->set("refresh", 0);
@@ -2121,30 +2161,20 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
     if (endTrack == startTrack) {
         //mlt_service_lock(service.get_service());
         Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
-        if (forceProducer) {
-            if (clipProducer.is_blank()) {
-                kDebug() << "// ERROR RESTTING CLIP PROD: " << moveEnd << ", TRK: " << startTrack;
-                mlt_service_unlock(m_mltConsumer->get_service());
-                m_isBlocked = false;
-                return false;
-            }
-            trackPlaylist.insert(clipProducer, moveEnd, clipProducer.get_in(), clipProducer.get_out());
+        if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer.is_blank()) {
+            // error, destination is not empty
+            //int ix = trackPlaylist.get_clip_index_at(moveEnd);
+            kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
+            mlt_service_unlock(m_mltConsumer->get_service());
+            m_isBlocked = false;
+            return false;
         } else {
-            if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer.is_blank()) {
-                // error, destination is not empty
-                //int ix = trackPlaylist.get_clip_index_at(moveEnd);
-                kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
-                mlt_service_unlock(m_mltConsumer->get_service());
-                m_isBlocked = false;
-                return false;
-            } else {
-                trackPlaylist.consolidate_blanks(0);
-                int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
-                /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
-                              mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
-                }*/
-                if (newIndex + 1 == trackPlaylist.count()) checkLength = true;
-            }
+            trackPlaylist.consolidate_blanks(0);
+            int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
+            /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
+            mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
+            }*/
+            if (newIndex + 1 == trackPlaylist.count()) checkLength = true;
         }
         //mlt_service_unlock(service.get_service());
     } else {
@@ -2669,8 +2699,34 @@ void Render::mltInsertTrack(int ix) {
 void Render::mltDeleteTrack(int ix) {
     QDomDocument doc;
     doc.setContent(sceneList(), false);
+    int tracksCount = doc.elementsByTagName("track").count() - 1;
     QDomNode track = doc.elementsByTagName("track").at(ix);
     QDomNode tractor = doc.elementsByTagName("tractor").at(0);
+    QDomNodeList transitions = doc.elementsByTagName("transition");
+    for (int i = 0; i < transitions.count(); i++) {
+        QDomElement e = transitions.at(i).toElement();
+        QDomNodeList props = e.elementsByTagName("property");
+        QMap <QString, QString> mappedProps;
+        for (int j = 0; j < props.count(); j++) {
+            QDomElement f = props.at(j).toElement();
+            mappedProps.insert(f.attribute("name"), f.firstChild().nodeValue());
+        }
+        if (mappedProps.value("mlt_service") == "mix" && mappedProps.value("b_track").toInt() == tracksCount) {
+            tractor.removeChild(transitions.at(i));
+        } else if (mappedProps.value("mlt_service") != "mix" && mappedProps.value("b_track").toInt() >= ix) {
+            // Transition needs to be moved
+            int a_track = mappedProps.value("a_track").toInt();
+            int b_track = mappedProps.value("b_track").toInt();
+            if (a_track > 0) a_track --;
+            if (b_track > 0) b_track --;
+            for (int j = 0; j < props.count(); j++) {
+                QDomElement f = props.at(j).toElement();
+                if (f.attribute("name") == "a_track") f.firstChild().setNodeValue(QString::number(a_track));
+                else if (f.attribute("name") == "b_track") f.firstChild().setNodeValue(QString::number(b_track));
+            }
+
+        }
+    }
     tractor.removeChild(track);
     setSceneList(doc.toString(), m_framePosition);
     return;
index cb5dcd2d4fd0a28b10ad2c3fd7cf04e8f84a82f7..1d7418269c1236526026da5c592b5da672487252 100644 (file)
@@ -154,8 +154,8 @@ Q_OBJECT public:
     int mltGetSpaceLength(const GenTime pos, int track);
     bool mltResizeClipEnd(ItemInfo info, GenTime clipDuration);
     bool mltResizeClipStart(ItemInfo info, GenTime diff);
-    bool mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart, Mlt::Producer *prod, bool forceProducer = false);
-    bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart, Mlt::Producer *prod, bool forceProducer = false);
+    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);
@@ -173,6 +173,7 @@ Q_OBJECT public:
     void mltResizeTransparency(int oldStart, int newStart, int newEnd, int track, int id);
     void mltInsertTrack(int ix);
     void mltDeleteTrack(int ix);
+    void mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod);
 
     /** Change speed of a clip in playlist. To do this, we create a new "framebuffer" producer.
     This new producer must have its "resource" param set to: video.mpg?0.6 where video.mpg is the path