[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdenlive/refactoring_timeline] src/timeline2/model: much cleaner timewarping
From:       Nicolas Carion <null () kde ! org>
Date:       2018-04-30 22:26:41
Message-ID: E1fDHFp-0003w7-Ii () code ! kde ! org
[Download RAW message or body]

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/clipmodel.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, oldDuration, \
m_producer->get_playtime(), reverse, operation, logUndo); +        if (logUndo) {
+            adjustEffectLength(right, old_in, inPoint, oldDuration, \
m_producer->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") == QLatin1String("timewarp")) {
-        // slowmotion producer, keep it
-        int space = -1;
-        if (m_currentTrackId != -1) {
-            if (auto ptr = m_parent.lock()) {
-                space = \
                ptr->getTrackById(m_currentTrackId)->getBlankSizeNearClip(m_id, \
                true);
-            } else {
-                qDebug() << "Error : Moving clip failed because parent timeline is \
                not available anymore";
-                Q_ASSERT(false);
-            }
-        }
-        std::function<bool(void)> local_undo = []() { return true; };
-        std::function<bool(void)> local_redo = []() { return true; };
-        useTimewarpProducer(m_producer->get_double("warp_speed"), space, local_undo, \
                local_redo);
-        return;
-    }
     int in = getIn();
     int out = getOut();
     std::shared_ptr<ProjectClip> binClip = \
                pCore->projectItemModel()->getClipByBinID(m_binClipId);
-    std::shared_ptr<Mlt::Producer> binProducer = binClip->getTimelineProducer(m_id, \
state); +    std::shared_ptr<Mlt::Producer> binProducer = \
binClip->getTimelineProducer(m_id, state, m_speed);  m_producer = \
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 &undo, Fun \
&redo)  {
+    if (m_endlessResize) {
+        // no timewarp for endless producers
+        return false;
+    }
+    std::function<bool(void)> local_undo = []() { return true; };
+    std::function<bool(void)> local_redo = []() { return true; };
     double previousSpeed = getSpeed();
-    auto operation = useTimewarpProducer_lambda(speed, extraSpace);
+    int new_in = int(double(getIn()) * previousSpeed / speed);
+    int new_out = int(double(getOut()) * previousSpeed / speed);
+    auto operation = useTimewarpProducer_lambda(speed);
     if (operation()) {
-        auto reverse = useTimewarpProducer_lambda(previousSpeed, extraSpace);
-        UPDATE_UNDO_REDO(operation, reverse, undo, redo);
+        auto reverse = useTimewarpProducer_lambda(previousSpeed);
+        UPDATE_UNDO_REDO(operation, reverse, local_undo, local_redo);
+        bool res = requestResize(new_out - new_in + 1, true, local_undo, local_redo, \
true); +        if (!res) {
+            bool undone = 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 = getIn();
-    int out = getOut();
-    int warp_in;
-    int warp_out;
-    if (getProperty("mlt_service") == QLatin1String("timewarp")) {
-        // slowmotion producer, get current speed
-        warp_in = m_producer->get_int("warp_in");
-        warp_out = m_producer->get_int("warp_out");
-    } else {
-        // store original in/out
-        warp_in = in;
-        warp_out = out;
-    }
-    in = warp_in / speed;
-    out = qMin((int)(warp_out / speed), extraSpace);
-    std::shared_ptr<ProjectClip> binClip = \
                pCore->projectItemModel()->getClipByBinID(m_binClipId);
-    std::shared_ptr<Mlt::Producer> originalProducer = binClip->originalProducer();
-    bool limitedDuration = binClip->hasLimitedDuration();
-
-    return [originalProducer, speed, in, out, warp_in, warp_out, limitedDuration, \
                this]() {
-        if (qFuzzyCompare(speed, 1.0)) {
-            m_producer.reset(originalProducer->cut(in, out));
-        } else {
-            QLocale locale;
-            QString resource = \
QString("timewarp:%1:%2").arg(locale.toString(speed)).arg(originalProducer->get("resource"));
                
-            std::shared_ptr<Mlt::Producer> warpProducer(new \
                Mlt::Producer(*m_producer->profile(), \
                resource.toUtf8().constData()));
-            // Make sure we use a cut so that the source producer in/out are 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 = !limitedDuration;
+    return [speed, this]() {
+        m_speed = 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") == 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/clipmodel.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 \
                originalDuration, Fun &undo, Fun &redo);
-    void passTimelineProperties(std::shared_ptr <ClipModel> other);
+    void passTimelineProperties(std::shared_ptr<ClipModel> other);
     KeyframeModel *getKeyframeModel();
 
     int fadeIn() const;
@@ -133,15 +133,19 @@ protected:
     bool requestResize(int size, bool right, Fun &undo, Fun &redo, bool logUndo = \
true) override;  
     /* @brief This function change the global (timeline-wise) enabled state of the \
                effects
-    */
+     */
     void setTimelineEffectsEnabled(bool enabled);
 
     /* @brief This functions should be called when the producer of the binClip \
changes, to allow refresh */  void refreshProducerFromBin(PlaylistState::ClipState \
state);  void refreshProducerFromBin();
-    /* @brief This functions replaces the current producer with a slowmotion one */
+
+    /* @brief This functions replaces the current producer with a slowmotion 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 untouched)
+    Fun useTimewarpProducer_lambda(double speed);
 
     /** @brief Returns the marker model associated with this clip */
     std::shared_ptr<MarkerListModel> getMarkerModel() const;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic