From e0706c69456a64eea5cb22b3909ff9299142b685 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Sun, 27 Sep 2009 08:38:10 +0000 Subject: [PATCH] Fix most of the effect stack corruptions when moving or disabling / enabling an effect svn path=/trunk/kdenlive/; revision=3945 --- src/customtrackview.cpp | 11 ++++- src/renderer.cpp | 104 ++++++++++++++++++++++++++++++++-------- src/renderer.h | 7 +++ 3 files changed, 100 insertions(+), 22 deletions(-) diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 8f0c0e10..e6dfeabb 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -1380,7 +1380,8 @@ void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) int strobe = EffectsList::parameter(effect, "strobe").toInt(); if (strobe == 0) strobe = 1; doChangeClipSpeed(info, speed, 1.0, strobe, clip->baseClip()->getId()); - clip->addEffect(effect); + EffectsParameterList params = clip->addEffect(effect); + m_document->renderer()->mltAddEffect(track, pos, params); if (clip->isSelected()) emit clipItemSelected(clip); return; } @@ -1403,6 +1404,7 @@ void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId()); clip->deleteEffect(index); emit clipItemSelected(clip); + m_document->renderer()->mltRemoveEffect(track, pos, index, true); return; } } @@ -1589,7 +1591,12 @@ void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos) QDomElement before = clip->effectAt(oldPos - 1).cloneNode().toElement(); clip->setEffectAt(oldPos - 1, act); clip->setEffectAt(newPos - 1, before); - m_document->renderer()->mltMoveEffect(track, pos, oldPos, newPos); + // special case: speed effect, which is a pseudo-effect, not appearing in MLT's effects + if (act.attribute("id") == "speed") { + m_document->renderer()->mltUpdateEffectPosition(track, pos, oldPos, newPos); + } else if (before.attribute("id") == "speed") { + m_document->renderer()->mltUpdateEffectPosition(track, pos, newPos, oldPos); + } else m_document->renderer()->mltMoveEffect(track, pos, oldPos, newPos); emit clipItemSelected(clip, newPos - 1); setDocumentModified(); } else emit displayMessage(i18n("Cannot move effect"), ErrorMessage); diff --git a/src/renderer.cpp b/src/renderer.cpp index 1c397d3b..904e9430 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -2185,15 +2185,45 @@ bool Render::mltAddEffect(int track, GenTime position, EffectsParameterList para Mlt::Service clipService(clip->get_service()); m_isBlocked = true; int duration = clip->get_playtime(); + bool updateIndex = false; delete clip; - // temporarily remove all effects after insert point - QList filtersList; + const int filter_ix = params.paramValue("kdenlive_ix").toInt(); int ct = 0; Mlt::Filter *filter = clipService.filter(ct); + while (filter) { + if (QString(filter->get("kdenlive_ix")).toInt() == filter_ix) { + // A filter at that position already existed, so we will increase all indexes later + updateIndex = true; + break; + } + ct++; + filter = clipService.filter(ct); + } + + if (params.paramValue("id") == "speed") { + // special case, speed effect is not really inserted, we just update the other effects index (kdenlive_ix) + ct = 0; + filter = clipService.filter(ct); + while (filter) { + if (QString(filter->get("kdenlive_ix")).toInt() >= filter_ix) { + if (updateIndex) filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() + 1); + } + ct++; + filter = clipService.filter(ct); + } + m_isBlocked = false; + if (doRefresh) refresh(); + return true; + } + + + // temporarily remove all effects after insert point + QList filtersList; + ct = 0; + filter = clipService.filter(ct); while (filter) { if (QString(filter->get("kdenlive_ix")).toInt() >= filter_ix) { - filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() + 1); filtersList.append(filter); clipService.detach(*filter); } else ct++; @@ -2300,7 +2330,10 @@ bool Render::mltAddEffect(int track, GenTime position, EffectsParameterList para // re-add following filters for (int i = 0; i < filtersList.count(); i++) { - clipService.attach(*(filtersList.at(i))); + Mlt::Filter *filter = filtersList.at(i); + if (updateIndex) + filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() + 1); + clipService.attach(*filter); } m_isBlocked = false; if (doRefresh) refresh(); @@ -2336,6 +2369,19 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par m_isBlocked = true; int ct = 0; Mlt::Filter *filter = clipService.filter(ct); + + /* + kDebug() << "EDITING FILTER: "<get("kdenlive_id") <<", IX: "<get("kdenlive_ix"); + ct++; + filter = clipService.filter(ct); + } + kDebug() << "++++++++++++++++++++++++++"; + */ + ct = 0; + filter = clipService.filter(ct); while (filter) { if (filter->get("kdenlive_ix") == index) { break; @@ -2345,24 +2391,10 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par } if (!filter) { - kDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT!!!!!"; + kDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT! " << index << ", " << tag; // filter was not found, it was probably a disabled filter, so add it to the correct place... - int ct = 0; - filter = clipService.filter(ct); - QList filtersList; - while (filter) { - if (QString(filter->get("kdenlive_ix")).toInt() > index.toInt()) { - filtersList.append(filter); - clipService.detach(*filter); - } else ct++; - filter = clipService.filter(ct); - } - bool success = mltAddEffect(track, position, params); - - for (int i = 0; i < filtersList.count(); i++) { - clipService.attach(*(filtersList.at(i))); - } + bool success = mltAddEffect(track, position, params); m_isBlocked = false; return success; } @@ -2381,6 +2413,38 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par return true; } +void Render::mltUpdateEffectPosition(int track, GenTime position, int oldPos, int newPos) +{ + + kDebug() << "MOVING EFFECT FROM " << oldPos << ", TO: " << newPos; + Mlt::Service service(m_mltProducer->parent().get_service()); + + 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(position.frames(m_fps)); + Mlt::Producer *clip = trackPlaylist.get_clip_at((int) position.frames(m_fps)); + if (!clip) { + kDebug() << "WARINIG, CANNOT FIND CLIP ON track: " << track << ", AT POS: " << position.frames(m_fps); + return; + } + Mlt::Service clipService(clip->get_service()); + delete clip; + m_isBlocked = true; + int ct = 0; + Mlt::Filter *filter = clipService.filter(ct); + while (filter) { + int pos = QString(filter->get("kdenlive_ix")).toInt(); + if (pos == oldPos) { + filter->set("kdenlive_ix", newPos); + } else ct++; + filter = clipService.filter(ct); + } + + m_isBlocked = false; + refresh(); +} + void Render::mltMoveEffect(int track, GenTime position, int oldPos, int newPos) { diff --git a/src/renderer.h b/src/renderer.h index 241459a1..f1790149 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -181,10 +181,17 @@ Q_OBJECT public: 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); + /** Delete an effect to a clip in MLT's playlist */ bool mltRemoveEffect(int track, GenTime position, QString index, bool updateIndex, bool doRefresh = true); + /** Add an effect to a clip in MLT's playlist */ bool mltAddEffect(int track, GenTime position, EffectsParameterList params, bool doRefresh = true); + /** Edit an effect parameters in MLT */ bool mltEditEffect(int track, GenTime position, EffectsParameterList params); + /** This only updates the "kdenlive_ix" (index) value of an effect */ + void mltUpdateEffectPosition(int track, GenTime position, int oldPos, int newPos); + /** This changes the order of effects in MLT, inverting effects from oldPos and newPos, also updating the kdenlive_ix value */ void mltMoveEffect(int track, GenTime position, int oldPos, int newPos); + /** This changes the state of a track, enabling / disabling audio and video */ void mltChangeTrackState(int track, bool mute, bool blind); bool mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut); bool mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool refresh = true); -- 2.39.5