From 8c50ce7ae0d522d66089015e44e05b70600d40a7 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Thu, 25 Jun 2009 19:41:15 +0000 Subject: [PATCH] Fix several issues with clips with speed changed: * 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 | 5 ---- src/abstractclipitem.h | 1 - src/clipdurationdialog.cpp | 2 +- src/clipitem.cpp | 22 +++++++------- src/customtrackview.cpp | 16 +++++------ src/mainwindow.cpp | 6 ++-- src/renderer.cpp | 59 ++++++++++++++++++++++---------------- src/renderer.h | 3 +- src/transitionsettings.cpp | 6 ++-- 9 files changed, 62 insertions(+), 58 deletions(-) diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index 0008c8b1..c0d8edcc 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -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; diff --git a/src/abstractclipitem.h b/src/abstractclipitem.h index b3a9f460..b3f34e5c 100644 --- a/src/abstractclipitem.h +++ b/src/abstractclipitem.h @@ -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); diff --git a/src/clipdurationdialog.cpp b/src/clipdurationdialog.cpp index b1a06c65..453c9945 100644 --- a/src/clipdurationdialog.cpp +++ b/src/clipdurationdialog.cpp @@ -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())); diff --git a/src/clipitem.cpp b/src/clipitem.cpp index bcc7af5e..5e39eb57 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -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 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 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); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 6d877f12..f558336f 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -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 (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 offsetList, bool skipSelectedItems) { QList snaps; - if (selected && offsetList.isEmpty()) offsetList.append(selected->duration()); + if (selected && offsetList.isEmpty()) offsetList.append(selected->cropDuration()); QList 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; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9809c7d5..95a20907 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -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(); } } diff --git a/src/renderer.cpp b/src/renderer.cpp index e3b91a9d..eefceb5e 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1739,6 +1739,24 @@ void Render::mltInsertSpace(QMap trackClipStartList, QMap 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); diff --git a/src/renderer.h b/src/renderer.h index ecbf6bc3..0fdd8dae 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -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 mltGetTransitionParamsFromXml(QDomElement xml); QMap m_slowmotionProducers; void buildConsumer(); diff --git a/src/transitionsettings.cpp b/src/transitionsettings.cpp index f5e42c11..2b2aecf3 100644 --- a/src/transitionsettings.cpp +++ b/src/transitionsettings.cpp @@ -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); -- 2.39.2