]> git.sesse.net Git - kdenlive/commitdiff
Fix several issues with clips with speed changed:
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Thu, 25 Jun 2009 19:41:15 +0000 (19:41 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Thu, 25 Jun 2009 19:41:15 +0000 (19:41 +0000)
* Fix fade to black:
http://www.kdenlive.org/mantis/view.php?id=819
* Fix display of markers & snap points
* Don't loose all effects when changing a clip speed

svn path=/trunk/kdenlive/; revision=3660

src/abstractclipitem.cpp
src/abstractclipitem.h
src/clipdurationdialog.cpp
src/clipitem.cpp
src/customtrackview.cpp
src/mainwindow.cpp
src/renderer.cpp
src/renderer.h
src/transitionsettings.cpp

index 0008c8b157a20e573866f446974ff4a4339aaf37..c0d8edccd2a62b78f91eb189497aaf7516668581 100644 (file)
@@ -169,11 +169,6 @@ void AbstractClipItem::resizeEnd(int posx, double speed, bool /*updateKeyFrames*
     }
 }
 
-GenTime AbstractClipItem::duration() const
-{
-    return m_cropDuration;
-}
-
 GenTime AbstractClipItem::startPos() const
 {
     return m_startPos;
index b3a9f460b6514e8ba0cc80fdf293733974eaa8e7..b3f34e5c2ba2287c17efe4e722a842f166f8cd3e 100644 (file)
@@ -55,7 +55,6 @@ public:
     virtual GenTime cropDuration() const ;
     virtual void resizeStart(int posx, double speed = 1.0);
     virtual void resizeEnd(int posx, double speed = 1.0, bool updateKeyFrames = true);
-    virtual GenTime duration() const;
     virtual double fps() const;
     virtual GenTime maxDuration() const;
     virtual void setCropStart(GenTime pos);
index b1a06c65240ebee54837ba02f193965b232b048c..453c9945e1588c143630d4338425ddfc25f41e8b 100644 (file)
@@ -52,7 +52,7 @@ ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, Timecode tc, QWid
 
     m_view.clip_position->setText(tc.getTimecode(m_clip->startPos(), m_fps));
     m_view.crop_position->setText(tc.getTimecode(m_clip->cropStart(), m_fps));
-    m_view.clip_duration->setText(tc.getTimecode(m_clip->duration(), m_fps));
+    m_view.clip_duration->setText(tc.getTimecode(m_clip->cropDuration(), m_fps));
     connect(m_view.position_up, SIGNAL(clicked()), this, SLOT(slotPosUp()));
     connect(m_view.position_down, SIGNAL(clicked()), this, SLOT(slotPosDown()));
     connect(m_view.crop_up, SIGNAL(clicked()), this, SLOT(slotCropUp()));
index bcc7af5efae547243c6bdc437ec05ec319466d42..5e39eb574af9ebde184944aaf18b94c28c1d0777 100644 (file)
@@ -182,7 +182,7 @@ void ClipItem::initEffect(QDomElement effect)
     }
     if (effect.attribute("tag") == "volume" || effect.attribute("tag") == "brightness") {
         if (effect.attribute("id") == "fadeout" || effect.attribute("id") == "fade_to_black") {
-            int end = (duration() + cropStart()).frames(m_fps);
+            int end = (cropDuration() + cropStart()).frames(m_fps);
             int start = end;
             if (effect.attribute("id") == "fadeout") {
                 if (m_effectList.hasEffect(QString(), "fade_to_black") == -1) {
@@ -739,9 +739,9 @@ void ClipItem::paint(QPainter *painter,
     pen.setStyle(Qt::DotLine);
     painter->setPen(pen);
     for (; it != markers.end(); ++it) {
-        pos = (*it).time() - cropStart();
+        pos = (*it).time() / m_speed - cropStart();
         if (pos > GenTime()) {
-            if (pos > duration()) break;
+            if (pos > cropDuration()) break;
             QLineF l(br.x() + pos.frames(m_fps), br.y(), br.x() + pos.frames(m_fps), br.bottom());
             QLineF l2 = painter->matrix().map(l);
             //framepos = scale * pos.frames(m_fps);
@@ -907,7 +907,7 @@ OPERATIONTYPE ClipItem::operationMode(QPointF pos)
         else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_endFade, m_fps).seconds()));
         return FADEOUT;
     } else if ((rect.right() - pos.x() < maximumOffset) && (rect.bottom() - pos.y() > addtransitionOffset)) {
-        setToolTip(i18n("Clip duration: %1s", duration().seconds()));
+        setToolTip(i18n("Clip duration: %1s", cropDuration().seconds()));
         return RESIZEEND;
     } else if ((pos.x() - rect.x() < 16 / scale) && (rect.bottom() - pos.y() <= addtransitionOffset)) {
         setToolTip(i18n("Add transition"));
@@ -927,9 +927,9 @@ QList <GenTime> ClipItem::snapMarkers() const
     GenTime pos;
 
     for (int i = 0; i < markers.size(); i++) {
-        pos = markers.at(i) - cropStart();
+        pos = markers.at(i) / m_speed - cropStart();
         if (pos > GenTime()) {
-            if (pos > duration()) break;
+            if (pos > cropDuration()) break;
             else snaps.append(pos + startPos());
         }
     }
@@ -943,9 +943,9 @@ QList <CommentedTime> ClipItem::commentedSnapMarkers() const
     GenTime pos;
 
     for (int i = 0; i < markers.size(); i++) {
-        pos = markers.at(i).time() - cropStart();
+        pos = markers.at(i).time() / m_speed - cropStart();
         if (pos > GenTime()) {
-            if (pos > duration()) break;
+            if (pos > cropDuration()) break;
             else snaps.append(CommentedTime(pos + startPos(), markers.at(i).comment()));
         }
     }
@@ -1141,10 +1141,10 @@ void ClipItem::resizeEnd(int posx, double /*speed*/, bool updateKeyFrames)
     if (posx > max && maxDuration() != GenTime()) posx = max;
     if (posx == endPos().frames(m_fps)) return;
     //kDebug() << "// NEW POS: " << posx << ", OLD END: " << endPos().frames(m_fps);
-    const int previous = (cropStart() + duration()).frames(m_fps);
+    const int previous = (cropStart() + cropDuration()).frames(m_fps);
     AbstractClipItem::resizeEnd(posx, m_speed);
-    if ((int)(cropStart() + duration()).frames(m_fps) != previous) {
-        if (updateKeyFrames) checkEffectsKeyframesPos(previous, (cropStart() + duration()).frames(m_fps), false);
+    if ((int)(cropStart() + cropDuration()).frames(m_fps) != previous) {
+        if (updateKeyFrames) checkEffectsKeyframesPos(previous, (cropStart() + cropDuration()).frames(m_fps), false);
         if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
             /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
             m_endThumbTimer->start(150);
index 6d877f125b9a71ce39e378678a53105d4ff1326d..f558336fd57fbc97716e72f3f4c6d3a1879fe71f 100644 (file)
@@ -1062,7 +1062,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event)
                 QUndoCommand *moveCommand = new QUndoCommand();
                 moveCommand->setText(i18n("Edit clip"));
                 ItemInfo clipInfo = m_dragItem->info();
-                if (d.duration() < m_dragItem->duration() || d.cropStart() != clipInfo.cropStart) {
+                if (d.duration() < m_dragItem->cropDuration() || d.cropStart() != clipInfo.cropStart) {
                     // duration was reduced, so process it first
                     ItemInfo startInfo = clipInfo;
                     clipInfo.endPos = clipInfo.startPos + d.duration();
@@ -1075,7 +1075,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event)
                     clipInfo.endPos = m_dragItem->endPos() + (clipInfo.startPos - startInfo.startPos);
                     new MoveClipCommand(this, startInfo, clipInfo, true, moveCommand);
                 }
-                if (d.duration() > m_dragItem->duration()) {
+                if (d.duration() > m_dragItem->cropDuration()) {
                     // duration was increased, so process it after move
                     ItemInfo startInfo = clipInfo;
                     clipInfo.endPos = clipInfo.startPos + d.duration();
@@ -1206,7 +1206,7 @@ bool CustomTrackView::insertPossible(AbstractGroupItem *group, const QPoint &pos
             ClipItem *clip = static_cast <ClipItem *>(children.at(i));
             ItemInfo info = clip->info();
             kDebug() << " / / INSERT : " << pos.x();
-            QRectF shape = QRectF(clip->startPos().frames(m_document->fps()), clip->track() * m_tracksHeight + 1, clip->duration().frames(m_document->fps()) - 0.02, m_tracksHeight - 1);
+            QRectF shape = QRectF(clip->startPos().frames(m_document->fps()), clip->track() * m_tracksHeight + 1, clip->cropDuration().frames(m_document->fps()) - 0.02, m_tracksHeight - 1);
             kDebug() << " / / INSERT RECT: " << shape;
             path = path.united(QPolygonF(shape));
         }
@@ -1558,7 +1558,7 @@ void CustomTrackView::slotAddTransitionToSelectedClips(QDomElement transition)
             ClipItem *transitionClip = NULL;
             const int transitiontrack = getPreviousVideoTrack(info.track);
             GenTime pos = GenTime((int)(mapToScene(m_menuPosition).x()), m_document->fps());
-            if (pos < item->startPos() + item->duration() / 2) {
+            if (pos < item->startPos() + item->cropDuration() / 2) {
                 // add transition to clip start
                 info.startPos = item->startPos();
                 if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_document->tracksCount() - transitiontrack);
@@ -2676,7 +2676,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         int ix = item->hasEffect("volume", "fadeout");
         if (ix != -1) {
             QDomElement oldeffect = item->effectAt(ix);
-            int end = (item->duration() + item->cropStart()).frames(m_document->fps());
+            int end = (item->cropDuration() + item->cropStart()).frames(m_document->fps());
             int start = item->fadeOut();
             if (start == 0) {
                 slotDeleteEffect(item, oldeffect);
@@ -2698,7 +2698,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         ix = item->hasEffect("brightness", "fade_to_black");
         if (ix != -1) {
             QDomElement oldeffect = item->effectAt(ix);
-            int end = (item->duration() + item->cropStart()).frames(m_document->fps());
+            int end = (item->cropDuration() + item->cropStart()).frames(m_document->fps());
             int start = item->fadeOut();
             if (start == 0) {
                 slotDeleteEffect(item, oldeffect);
@@ -3436,7 +3436,7 @@ double CustomTrackView::getSnapPointForPos(double pos)
 void CustomTrackView::updateSnapPoints(AbstractClipItem *selected, QList <GenTime> offsetList, bool skipSelectedItems)
 {
     QList <GenTime> snaps;
-    if (selected && offsetList.isEmpty()) offsetList.append(selected->duration());
+    if (selected && offsetList.isEmpty()) offsetList.append(selected->cropDuration());
     QList<QGraphicsItem *> itemList = items();
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i) == selected) continue;
@@ -4433,7 +4433,7 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, bool split)
             kDebug() << "// CHK DOC TRK:" << freetrack << ", DUR:" << m_document->renderer()->mltTrackDuration(freetrack);
             if (m_document->trackInfoAt(freetrack - 1).type == AUDIOTRACK) {
                 kDebug() << "// CHK DOC TRK:" << freetrack << ", DUR:" << m_document->renderer()->mltTrackDuration(freetrack);
-                if (m_document->renderer()->mltTrackDuration(freetrack) < start || m_document->renderer()->mltGetSpaceLength(pos, freetrack, false) >= clip->duration().frames(m_document->fps())) {
+                if (m_document->renderer()->mltTrackDuration(freetrack) < start || m_document->renderer()->mltGetSpaceLength(pos, freetrack, false) >= clip->cropDuration().frames(m_document->fps())) {
                     kDebug() << "FOUND SPACE ON TRK: " << freetrack;
                     break;
                 }
index 9809c7d548da9647dafb19f0f9b2cf13b9856f83..95a20907095d09f9acf9d32d4411b4de83aab1d0 100644 (file)
@@ -1935,7 +1935,7 @@ void MainWindow::slotAddClipMarker()
         if (m_activeTimeline) {
             ClipItem *item = m_activeTimeline->projectView()->getActiveClipUnderCursor();
             if (item) {
-                pos = m_projectMonitor->position() - item->startPos() + item->cropStart();
+                pos = (m_projectMonitor->position() - item->startPos() + item->cropStart()) / item->speed();
                 clip = item->baseClip();
             }
         }
@@ -1964,7 +1964,7 @@ void MainWindow::slotDeleteClipMarker()
         if (m_activeTimeline) {
             ClipItem *item = m_activeTimeline->projectView()->getActiveClipUnderCursor();
             if (item) {
-                pos = m_projectMonitor->position() - item->startPos() + item->cropStart();
+                pos = (m_projectMonitor->position() - item->startPos() + item->cropStart()) / item->speed();
                 clip = item->baseClip();
             }
         }
@@ -2017,7 +2017,7 @@ void MainWindow::slotEditClipMarker()
         if (m_activeTimeline) {
             ClipItem *item = m_activeTimeline->projectView()->getActiveClipUnderCursor();
             if (item) {
-                pos = m_projectMonitor->position() - item->startPos() + item->cropStart();
+                pos = (m_projectMonitor->position() - item->startPos() + item->cropStart()) / item->speed();
                 clip = item->baseClip();
             }
         }
index e3b91a9d0a70cbc2ef1bb1f91dec1c7cea85fb9d..eefceb5e59ee86638c9ccdd5e964cc1c5c1f2de0 100644 (file)
@@ -1739,6 +1739,24 @@ void Render::mltInsertSpace(QMap <int, int> trackClipStartList, QMap <int, int>
     m_mltConsumer->set("refresh", 1);
 }
 
+
+void Render::mltPasteEffects(Mlt::Producer *source, Mlt::Producer *dest)
+{
+    Mlt::Service sourceService(source->get_service());
+    Mlt::Service destService(dest->get_service());
+
+    // move all effects to the correct producer
+    int ct = 0;
+    Mlt::Filter *filter = sourceService.filter(ct);
+    while (filter) {
+        if (filter->get("kdenlive_ix") != 0) {
+            sourceService.detach(*filter);
+            destService.attach(*filter);
+        } else ct++;
+        filter = sourceService.filter(ct);
+    }
+}
+
 int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod)
 {
     m_isBlocked = true;
@@ -1768,7 +1786,7 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
         delete clip;
         return -1;
     }
-    delete clip;
+
     QString serv = clipparent.get("mlt_service");
     QString id = clipparent.get("id");
     //kDebug() << "CLIP SERVICE: " << serv;
@@ -1797,6 +1815,10 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
             GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
             cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)(info.cropStart.frames(m_fps) / speed + maxLength.frames(m_fps) - 1));
         } else cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)((info.cropStart.frames(m_fps) + clipLength) / speed - 1));
+
+        // move all effects to the correct producer
+        mltPasteEffects(clip, cut);
+
         trackPlaylist.insert_at(startPos, *cut, 1);
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
@@ -1818,6 +1840,10 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
             GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
             cut = prod->cut((int)(info.cropStart.frames(m_fps)), (int)(info.cropStart.frames(m_fps) + maxLength.frames(m_fps) - 1));
         } else cut = prod->cut((int)(info.cropStart.frames(m_fps)), (int)((info.cropStart + newDuration).frames(m_fps)) - 1);
+
+        // move all effects to the correct producer
+        mltPasteEffects(clip, cut);
+
         trackPlaylist.insert_at(startPos, *cut, 1);
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
@@ -1855,12 +1881,17 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
             cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)(info.cropStart.frames(m_fps) / speed + maxLength.frames(m_fps) - 1));
         } else cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)((info.cropStart / speed + newDuration).frames(m_fps) - 1));
 
+        // move all effects to the correct producer
+        mltPasteEffects(clip, cut);
+
         trackPlaylist.insert_at(startPos, *cut, 1);
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
 
         mlt_service_unlock(service.get_service());
     }
+
+    delete clip;
     if (clipIndex + 1 == trackPlaylist.count()) mltCheckLength();
     m_isBlocked = false;
     return newLength;
@@ -2400,18 +2431,7 @@ void Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod)
     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);
-    }
+    mltPasteEffects(&clipProducer, clip);
 
     trackPlaylist.insert_at(pos, clip, 1);
     mlt_service_unlock(m_mltConsumer->get_service());
@@ -2488,18 +2508,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             }
 
             // 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);
-            }
+            mltPasteEffects(&clipProducer, clip);
 
             int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
             destTrackPlaylist.consolidate_blanks(0);
index ecbf6bc3f376d95ffa5d71dc99e0350f9cec8566..0fdd8daea76ff16d20f88c04e5ae34e4a4bbc90b 100644 (file)
@@ -50,7 +50,7 @@ class Frame;
 class Producer;
 class Filter;
 class Profile;
-class Multitrack;
+class Service;
 };
 
 
@@ -221,6 +221,7 @@ private:   // Private attributes & methods
     /** Sets the description of this renderer to desc. */
     void closeMlt();
     void mltCheckLength();
+    void mltPasteEffects(Mlt::Producer *source, Mlt::Producer *dest);
     QMap<QString, QString> mltGetTransitionParamsFromXml(QDomElement xml);
     QMap<QString, Mlt::Producer *> m_slowmotionProducers;
     void buildConsumer();
index f5e42c114b171e7b717110d0962369e92cefe837..2b2aecf31ffc6fc5db2b6582f392bc8bef972505 100644 (file)
@@ -129,15 +129,15 @@ void TransitionSettings::slotTransitionItemSelected(Transition* t, int nextTrack
             else m_ui.transitionTrack->setCurrentIndex(0);
             m_ui.transitionTrack->blockSignals(false);
         }
-        if (update || t->duration() != m_transitionDuration || t->startPos() != m_transitionStart) {
-            m_transitionDuration = t->duration();
+        if (update || t->cropDuration() != m_transitionDuration || t->startPos() != m_transitionStart) {
+            m_transitionDuration = t->cropDuration();
             m_transitionStart = t->startPos();
             slotTransitionChanged(false, true);
         }
         return;
     } else if (update) return;
     if (t) {
-        m_transitionDuration = t->duration();
+        m_transitionDuration = t->cropDuration();
         m_transitionStart = t->startPos();
         m_ui.transitionTrack->blockSignals(true);
         if (!t->forcedTrack()) m_ui.transitionTrack->setCurrentIndex(0);