From kde-commits Mon Apr 30 22:26:41 2018 From: Nicolas Carion Date: Mon, 30 Apr 2018 22:26:41 +0000 To: kde-commits Subject: [kdenlive/refactoring_timeline] src/timeline2/model: much cleaner timewarping Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=152512721700602 Git commit 6785afa77d4b7a732e27d744a3023c3f1e7c628d by Nicolas Carion. Committed on 30/04/2018 at 22:27. Pushed by alcinos into branch 'refactoring_timeline'. much cleaner timewarping M +27 -68 src/timeline2/model/clipmodel.cpp M +8 -4 src/timeline2/model/clipmodel.hpp https://commits.kde.org/kdenlive/6785afa77d4b7a732e27d744a3023c3f1e7c628d diff --git a/src/timeline2/model/clipmodel.cpp b/src/timeline2/model/clipmo= del.cpp index a39f6f49a..e0a160ba8 100644 --- a/src/timeline2/model/clipmodel.cpp +++ b/src/timeline2/model/clipmodel.cpp @@ -189,7 +189,9 @@ bool ClipModel::requestResize(int size, bool right, Fun= &undo, Fun &redo, bool l return false; }; qDebug() << "// ADJUSTING EFFECT LENGTH, LOGUNDO " << logUndo << "= , " << old_in << "/" << inPoint << ", " << m_producer->get_playtime(); - if (logUndo) adjustEffectLength(right, old_in, inPoint, oldDuratio= n, m_producer->get_playtime(), reverse, operation, logUndo); + if (logUndo) { + adjustEffectLength(right, old_in, inPoint, oldDuration, m_prod= ucer->get_playtime(), reverse, operation, logUndo); + } UPDATE_UNDO_REDO(operation, reverse, undo, redo); return true; } @@ -324,26 +326,10 @@ bool ClipModel::isAudioOnly() const void ClipModel::refreshProducerFromBin(PlaylistState::ClipState state) { QWriteLocker locker(&m_lock); - if (getProperty("mlt_service") =3D=3D QLatin1String("timewarp")) { - // slowmotion producer, keep it - int space =3D -1; - if (m_currentTrackId !=3D -1) { - if (auto ptr =3D m_parent.lock()) { - space =3D ptr->getTrackById(m_currentTrackId)->getBlankSiz= eNearClip(m_id, true); - } else { - qDebug() << "Error : Moving clip failed because parent tim= eline is not available anymore"; - Q_ASSERT(false); - } - } - std::function local_undo =3D []() { return true; }; - std::function local_redo =3D []() { return true; }; - useTimewarpProducer(m_producer->get_double("warp_speed"), space, l= ocal_undo, local_redo); - return; - } int in =3D getIn(); int out =3D getOut(); std::shared_ptr binClip =3D pCore->projectItemModel()->ge= tClipByBinID(m_binClipId); - std::shared_ptr binProducer =3D binClip->getTimelinePro= ducer(m_id, state); + std::shared_ptr binProducer =3D binClip->getTimelinePro= ducer(m_id, state, m_speed); m_producer =3D std::move(binProducer); m_producer->set_in_and_out(in, out); // replant effect stack in updated service @@ -360,62 +346,39 @@ void ClipModel::refreshProducerFromBin() = bool ClipModel::useTimewarpProducer(double speed, int extraSpace, Fun &und= o, Fun &redo) { + if (m_endlessResize) { + // no timewarp for endless producers + return false; + } + std::function local_undo =3D []() { return true; }; + std::function local_redo =3D []() { return true; }; double previousSpeed =3D getSpeed(); - auto operation =3D useTimewarpProducer_lambda(speed, extraSpace); + int new_in =3D int(double(getIn()) * previousSpeed / speed); + int new_out =3D int(double(getOut()) * previousSpeed / speed); + auto operation =3D useTimewarpProducer_lambda(speed); if (operation()) { - auto reverse =3D useTimewarpProducer_lambda(previousSpeed, extraSp= ace); - UPDATE_UNDO_REDO(operation, reverse, undo, redo); + auto reverse =3D useTimewarpProducer_lambda(previousSpeed); + UPDATE_UNDO_REDO(operation, reverse, local_undo, local_redo); + bool res =3D requestResize(new_out - new_in + 1, true, local_undo,= local_redo, true); + if (!res) { + bool undone =3D local_undo(); + Q_ASSERT(undone); + return false; + } + UPDATE_UNDO_REDO(local_redo, local_undo, undo, redo); return true; } return false; } = -Fun ClipModel::useTimewarpProducer_lambda(double speed, int extraSpace) +Fun ClipModel::useTimewarpProducer_lambda(double speed) { - Q_UNUSED(extraSpace) - QWriteLocker locker(&m_lock); - // TODO: disable timewarp on color clips - int in =3D getIn(); - int out =3D getOut(); - int warp_in; - int warp_out; - if (getProperty("mlt_service") =3D=3D QLatin1String("timewarp")) { - // slowmotion producer, get current speed - warp_in =3D m_producer->get_int("warp_in"); - warp_out =3D m_producer->get_int("warp_out"); - } else { - // store original in/out - warp_in =3D in; - warp_out =3D out; - } - in =3D warp_in / speed; - out =3D qMin((int)(warp_out / speed), extraSpace); - std::shared_ptr binClip =3D pCore->projectItemModel()->ge= tClipByBinID(m_binClipId); - std::shared_ptr originalProducer =3D binClip->originalP= roducer(); - bool limitedDuration =3D binClip->hasLimitedDuration(); - - return [originalProducer, speed, in, out, warp_in, warp_out, limitedDu= ration, this]() { - if (qFuzzyCompare(speed, 1.0)) { - m_producer.reset(originalProducer->cut(in, out)); - } else { - QLocale locale; - QString resource =3D QString("timewarp:%1:%2").arg(locale.toSt= ring(speed)).arg(originalProducer->get("resource")); - std::shared_ptr warpProducer(new Mlt::Producer(= *m_producer->profile(), resource.toUtf8().constData())); - // Make sure we use a cut so that the source producer in/out a= re not modified - m_producer.reset(warpProducer->cut(0, warpProducer->get_length= ())); - setInOut(in, out); - } - // replant effect stack in updated service - m_effectStack->resetService(m_producer); - m_producer->set("kdenlive:id", m_binClipId.toUtf8().constData()); - m_producer->set("_kdenlive_cid", m_id); - m_producer->set("warp_in", warp_in); - m_producer->set("warp_out", warp_out); - m_endlessResize =3D !limitedDuration; + return [speed, this]() { + m_speed =3D speed; + refreshProducerFromBin(m_currentState); return true; }; - return []() { return false; }; } = QVariant ClipModel::getAudioWaveform() @@ -451,11 +414,7 @@ int ClipModel::fadeOut() const = double ClipModel::getSpeed() const { - if (getProperty("mlt_service") =3D=3D QLatin1String("timewarp")) { - // slowmotion producer, get current speed - return m_producer->parent().get_double("warp_speed"); - } - return 1.0; + return m_speed; } = KeyframeModel *ClipModel::getKeyframeModel() diff --git a/src/timeline2/model/clipmodel.hpp b/src/timeline2/model/clipmo= del.hpp index efbb3825b..ca24b57cb 100644 --- a/src/timeline2/model/clipmodel.hpp +++ b/src/timeline2/model/clipmodel.hpp @@ -106,7 +106,7 @@ public: /** @brief Adjust effects duration. Should be called after each resize= / cut operation */ bool adjustEffectLength(bool adjustFromEnd, int oldIn, int newIn, int = oldDuration, int duration, Fun &undo, Fun &redo, bool logUndo); bool adjustEffectLength(const QString &effectName, int duration, int o= riginalDuration, Fun &undo, Fun &redo); - void passTimelineProperties(std::shared_ptr other); + void passTimelineProperties(std::shared_ptr other); KeyframeModel *getKeyframeModel(); = int fadeIn() const; @@ -133,15 +133,19 @@ protected: bool requestResize(int size, bool right, Fun &undo, Fun &redo, bool lo= gUndo =3D true) override; = /* @brief This function change the global (timeline-wise) enabled stat= e of the effects - */ + */ void setTimelineEffectsEnabled(bool enabled); = /* @brief This functions should be called when the producer of the bin= Clip changes, to allow refresh */ void refreshProducerFromBin(PlaylistState::ClipState state); void refreshProducerFromBin(); - /* @brief This functions replaces the current producer with a slowmoti= on one */ + + /* @brief This functions replaces the current producer with a slowmoti= on one + It also resizes the producer so that set of frames contained in the= clip is the same + */ bool useTimewarpProducer(double speed, int extraSpace, Fun &undo, Fun = &redo); - Fun useTimewarpProducer_lambda(double speed, int extraSpace); + // @brief Lambda that merely changes the speed (in and out are untouch= ed) + Fun useTimewarpProducer_lambda(double speed); = /** @brief Returns the marker model associated with this clip */ std::shared_ptr getMarkerModel() const;