[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