[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdenlive/Applications/16.12] src: Fix many issues with volume keyframes
From: Jean-Baptiste Mardelle <jb () kdenlive ! org>
Date: 2016-11-30 23:06:22
Message-ID: E1cCDxG-00087z-TS () code ! kde ! org
[Download RAW message or body]
Git commit b348355e43285c37456bfc2625a055811b790b8f by Jean-Baptiste Mardelle.
Committed on 30/11/2016 at 23:05.
Pushed by mardelle into branch 'Applications/16.12'.
Fix many issues with volume keyframes
M +1 -1 src/doc/documentvalidator.cpp
M +5 -5 src/effectstack/widgets/animationwidget.cpp
M +1 -1 src/effectstack/widgets/animationwidget.h
M +11 -9 src/mltcontroller/effectscontroller.cpp
M +6 -5 src/timeline/abstractclipitem.cpp
M +3 -5 src/timeline/clipitem.cpp
M +1 -2 src/timeline/customtrackview.cpp
M +1 -2 src/timeline/effectmanager.cpp
M +62 -7 src/timeline/keyframeview.cpp
M +2 -0 src/timeline/keyframeview.h
M +3 -3 src/timeline/track.cpp
https://commits.kde.org/kdenlive/b348355e43285c37456bfc2625a055811b790b8f
diff --git a/src/doc/documentvalidator.cpp b/src/doc/documentvalidator.cpp
index 595f76f..7e524d6 100644
--- a/src/doc/documentvalidator.cpp
+++ b/src/doc/documentvalidator.cpp
@@ -1497,7 +1497,7 @@ bool DocumentValidator::upgrade(double version, const double \
currentVersion) }
}
EffectsList::setProperty(eff, conversionParams.at(2), \
parsedValues.join(";"));
- EffectsList::setProperty(eff, \
QStringLiteral("kdenlive:sync_in_out"), QStringLiteral("1")); + \
//EffectsList::setProperty(eff, QStringLiteral("kdenlive:sync_in_out"), \
QStringLiteral("1")); eff.setAttribute(QStringLiteral("out"), out);
}
}
diff --git a/src/effectstack/widgets/animationwidget.cpp \
b/src/effectstack/widgets/animationwidget.cpp index 71ab9d2..aaffa78 100644
--- a/src/effectstack/widgets/animationwidget.cpp
+++ b/src/effectstack/widgets/animationwidget.cpp
@@ -232,9 +232,9 @@ void AnimationWidget::finishSetup()
}
//static
-QString AnimationWidget::getDefaultKeyframes(const QString &defaultValue, bool \
linearOnly) +QString AnimationWidget::getDefaultKeyframes(int start, const QString \
&defaultValue, bool linearOnly) {
- QString keyframes = QStringLiteral("0");
+ QString keyframes = QString::number(start);
if (linearOnly) {
keyframes.append(QStringLiteral("="));
} else {
@@ -671,7 +671,7 @@ void AnimationWidget::addParameter(const QDomElement &e)
keyframes = e.attribute(QStringLiteral("value"));
}
if (keyframes.isEmpty()) {
- keyframes = getDefaultKeyframes(e.attribute(QStringLiteral("default")));
+ keyframes = getDefaultKeyframes(m_inPoint, \
e.attribute(QStringLiteral("default"))); if (keyframes.contains('%')) {
keyframes = \
EffectsController::getStringRectEval(m_monitor->profileInfo(), keyframes); }
@@ -1012,7 +1012,7 @@ void AnimationWidget::loadPresets(QString currentText)
QMap <QString, QVariant> defaultEntry;
QStringList paramNames = m_doubleWidgets.keys();
for (int i = 0; i < paramNames.count(); i++) {
- defaultEntry.insert(paramNames.at(i), \
getDefaultKeyframes(m_params.at(i).attribute(QStringLiteral("default")))); + \
defaultEntry.insert(paramNames.at(i), getDefaultKeyframes(m_inPoint, \
m_params.at(i).attribute(QStringLiteral("default")))); }
m_presetCombo->addItem(i18n("Default"), defaultEntry);
loadPreset(dir.absoluteFilePath(m_xml.attribute(QStringLiteral("type"))));
@@ -1304,7 +1304,7 @@ void AnimationWidget::reload(const QString &tag, const QString \
&data) if (!m_rectParameter.isEmpty() && tag != m_rectParameter) {
// reset geometry keyframes
// simple anim parameter, get default value
- QString def = getDefaultKeyframes(defaultValue(m_rectParameter));
+ QString def = getDefaultKeyframes(m_inPoint, defaultValue(m_rectParameter));
// Clear current keyframes
m_animProperties.set(m_rectParameter.toUtf8().constData(), \
def.toUtf8().constData()); // Add default keyframes
diff --git a/src/effectstack/widgets/animationwidget.h \
b/src/effectstack/widgets/animationwidget.h index 4e13503..869dae5 100644
--- a/src/effectstack/widgets/animationwidget.h
+++ b/src/effectstack/widgets/animationwidget.h
@@ -51,7 +51,7 @@ public:
void updateTimecodeFormat();
void addParameter(const QDomElement &e);
const QMap <QString, QString> getAnimation();
- static QString getDefaultKeyframes(const QString &defaultValue, bool linearOnly \
= false); + static QString getDefaultKeyframes(int start, const QString \
&defaultValue, bool linearOnly = false); void setActiveKeyframe(int frame);
void finishSetup();
/** @brief Returns true if currently active param is name */
diff --git a/src/mltcontroller/effectscontroller.cpp \
b/src/mltcontroller/effectscontroller.cpp index 2bc2ec9..026092f 100644
--- a/src/mltcontroller/effectscontroller.cpp
+++ b/src/mltcontroller/effectscontroller.cpp
@@ -103,8 +103,9 @@ EffectsParameterList EffectsController::getEffectArgs(const \
ProfileInfo &info, c
parameters.addParam(QStringLiteral("tag"), \
effect.attribute(QStringLiteral("tag")));
//if (effect.hasAttribute("region")) parameters.addParam("region", \
effect.attribute("region"));
parameters.addParam(QStringLiteral("kdenlive_ix"), \
effect.attribute(QStringLiteral("kdenlive_ix")));
- if (effect.hasAttribute(QStringLiteral("sync_in_out")))
+ if (effect.hasAttribute(QStringLiteral("sync_in_out"))) {
parameters.addParam(QStringLiteral("kdenlive:sync_in_out"), \
effect.attribute(QStringLiteral("sync_in_out"))); + }
parameters.addParam(QStringLiteral("kdenlive_info"), \
effect.attribute(QStringLiteral("kdenlive_info")));
parameters.addParam(QStringLiteral("id"), \
effect.attribute(QStringLiteral("id")));
if (effect.hasAttribute(QStringLiteral("src"))) \
parameters.addParam(QStringLiteral("src"), effect.attribute(QStringLiteral("src"))); \
@@ -137,10 +138,11 @@ void \
EffectsController::adjustEffectParameters(EffectsParameterList ¶meters, for (int \
i = 0; i < params.count(); ++i) { QDomElement e = params.item(i).toElement();
QString paramname = prefix + e.attribute(QStringLiteral("name"));
- if (e.attribute(QStringLiteral("type")) == QLatin1String("animated") || \
(e.attribute(QStringLiteral("type")) == QLatin1String("geometry") && \
!e.hasAttribute(QStringLiteral("fixed")))) { + /*if \
(e.attribute(QStringLiteral("type")) == QLatin1String("animated") || \
(e.attribute(QStringLiteral("type")) == QLatin1String("geometry") && \
!e.hasAttribute(QStringLiteral("fixed")))) {
// effects with geometry param need in / out synced with the clip, \
request it...
- //parameters.addParam(QStringLiteral("kdenlive:sync_in_out"), \
QStringLiteral("1"));
- }
+ parameters.addParam(QStringLiteral("kdenlive:sync_in_out"), \
QStringLiteral("1")); + qDebug()<<" ** * ADDIN EFFECT ANIM SYN TRUE";
+ }*/
if (e.attribute(QStringLiteral("type")) == QLatin1String("animated")) {
parameters.addParam(paramname, e.attribute(QStringLiteral("value")));
} else if (e.attribute(QStringLiteral("type")) == \
QLatin1String("simplekeyframe")) { @@ -229,7 +231,7 @@ void \
EffectsController::initTrackEffect(ProfileInfo pInfo, QDomElement effect) bool \
hasValue = e.hasAttribute(QStringLiteral("value"));
// Check if this effect has a variable parameter, init effects default value
if ((type == QLatin1String("animatedrect") || type == \
QLatin1String("geometry")) && !hasValue) {
- QString kfr = \
AnimationWidget::getDefaultKeyframes(e.attribute(QStringLiteral("default")), type == \
QLatin1String("geometry")); + QString kfr = \
AnimationWidget::getDefaultKeyframes(0, e.attribute(QStringLiteral("default")), type \
== QLatin1String("geometry")); if (kfr.contains("%")) {
kfr = EffectsController::getStringRectEval(pInfo, kfr);
}
@@ -244,7 +246,7 @@ void EffectsController::initTrackEffect(ProfileInfo pInfo, \
QDomElement effect)
} else e.setAttribute(QStringLiteral("value"), evaluatedValue);
} else {
if (type == QLatin1String("animated") && !hasValue) {
- e.setAttribute(QStringLiteral("value"), \
AnimationWidget::getDefaultKeyframes(e.attribute(QStringLiteral("default")))); + \
e.setAttribute(QStringLiteral("value"), AnimationWidget::getDefaultKeyframes(0, \
e.attribute(QStringLiteral("default")))); }
else if (!hasValue) {
e.setAttribute(QStringLiteral("value"), \
e.attribute(QStringLiteral("default"))); @@ -273,7 +275,7 @@ void \
EffectsController::initEffect(ItemInfo info, ProfileInfo pInfo, EffectsList bool \
hasValue = e.hasAttribute(QStringLiteral("value"));
// Check if this effect has a variable parameter, init effects default value
if ((type == QLatin1String("animatedrect") || type == \
QLatin1String("geometry")) && !hasValue) {
- QString kfr = \
AnimationWidget::getDefaultKeyframes(e.attribute(QStringLiteral("default")), type == \
QLatin1String("geometry")); + QString kfr = \
AnimationWidget::getDefaultKeyframes(info.cropStart.frames(fps), \
e.attribute(QStringLiteral("default")), type == QLatin1String("geometry")); if \
(kfr.contains("%")) { kfr = EffectsController::getStringRectEval(pInfo, kfr);
}
@@ -288,7 +290,7 @@ void EffectsController::initEffect(ItemInfo info, ProfileInfo \
pInfo, EffectsList
} else e.setAttribute(QStringLiteral("value"), evaluatedValue);
} else {
if (type == QLatin1String("animated") && !hasValue) {
- e.setAttribute(QStringLiteral("value"), \
AnimationWidget::getDefaultKeyframes(e.attribute(QStringLiteral("default")))); + \
e.setAttribute(QStringLiteral("value"), \
AnimationWidget::getDefaultKeyframes(info.cropStart.frames(fps), \
e.attribute(QStringLiteral("default")))); }
else if (!hasValue) {
e.setAttribute(QStringLiteral("value"), \
e.attribute(QStringLiteral("default"))); @@ -312,7 +314,7 @@ void \
EffectsController::initEffect(ItemInfo info, ProfileInfo pInfo, EffectsList }
}
- if (type.startsWith(QStringLiteral("animated")) || (type == \
QLatin1String("geometry") && !e.hasAttribute(QStringLiteral("fixed")))) { + if \
(EffectsList::parameter(effect, QStringLiteral("kdenlive:sync_in_out")) == \
QLatin1String("1") || (type == QLatin1String("geometry") && \
!e.hasAttribute(QStringLiteral("fixed")))) {
// Effects with a geometry parameter need to sync in / out with parent \
clip
effect.setAttribute(QStringLiteral("in"), QString::number((int) \
info.cropStart.frames(fps)));
effect.setAttribute(QStringLiteral("out"), QString::number((int) \
(info.cropStart + info.cropDuration).frames(fps) - 1));
diff --git a/src/timeline/abstractclipitem.cpp b/src/timeline/abstractclipitem.cpp
index 09c318e..4f4a876 100644
--- a/src/timeline/abstractclipitem.cpp
+++ b/src/timeline/abstractclipitem.cpp
@@ -200,7 +200,6 @@ void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, \
bool /*emitChang }
m_info.startPos += durationDiff;
m_keyframeView.setOffset(durationDiff.frames(m_fps));
-
// set to true if crop from start is negative (possible for color clips, images \
as they have no size limit) bool negCropStart = false;
if (type() == AVWidget) {
@@ -616,7 +615,7 @@ QString AbstractClipItem::resizeAnimations(QDomElement effect, \
int previousDurat
effect.setAttribute(QStringLiteral("out"), QString::number(start + \
duration)); }
else {
- keyframes = KeyframeView::cutAnimation(animation, cropstart, \
duration, previousDuration, false); + keyframes = \
KeyframeView::addBorderKeyframes(animation, cropstart, duration); }
// TODO: in case of multiple animated params, use _intimeline to detect \
active one e.setAttribute(QStringLiteral("value"), keyframes);
@@ -628,10 +627,12 @@ QString AbstractClipItem::resizeAnimations(QDomElement effect, \
int previousDurat bool AbstractClipItem::switchKeyframes(QDomElement param, int in, \
int oldin, int out, int oldout) {
QString animation = param.attribute(QStringLiteral("value"));
- if (in != oldin)
+ if (in != oldin) {
animation = KeyframeView::switchAnimation(animation, in, oldin, out, oldout, \
param.attribute(QStringLiteral("type")) == \
QLatin1String("animatedrect"));
- if (out != oldout)
- animation = KeyframeView::switchAnimation(animation, out - 1, oldout - 1, \
out, oldout, param.attribute(QStringLiteral("type")) == \
QLatin1String("animatedrect")); + }
+ if (out != oldout) {
+ animation = KeyframeView::switchAnimation(animation, out, oldout, out, \
oldout, param.attribute(QStringLiteral("type")) == QLatin1String("animatedrect")); + \
} if (animation != param.attribute(QStringLiteral("value"))) {
param.setAttribute(QStringLiteral("value"), animation);
return true;
diff --git a/src/timeline/clipitem.cpp b/src/timeline/clipitem.cpp
index 579a7d8..687b978 100644
--- a/src/timeline/clipitem.cpp
+++ b/src/timeline/clipitem.cpp
@@ -1453,7 +1453,7 @@ EffectsParameterList ClipItem::addEffect(ProfileInfo info, \
QDomElement effect, b
else if (e.attribute(QStringLiteral("type")) == \
QLatin1String("animated")) {
parameters.addParam(e.attribute(QStringLiteral("name")), \
e.attribute(QStringLiteral("value"))); // Effects with a animated parameter need to \
sync in / out with parent clip
- if (!e.hasAttribute(QStringLiteral("sync_in_out")) || \
e.attribute(QStringLiteral("sync_in_out")) == QLatin1String("1")) { + \
if (e.attribute(QStringLiteral("sync_in_out")) == QLatin1String("1")) { \
needInOutSync = true; }
} else if (e.attribute(QStringLiteral("type")) == \
QLatin1String("simplekeyframe")) { @@ -1808,10 +1808,9 @@ QMap<int, QDomElement> \
ClipItem::adjustEffectsToDuration(const ItemInfo &oldInfo
if (effect.attribute(QStringLiteral("sync_in_out")) == \
QLatin1String("1")) {
effect.setAttribute(QStringLiteral("in"), \
cropStart().frames(m_fps));
effect.setAttribute(QStringLiteral("out"), (cropStart() + \
cropDuration()).frames(m_fps) - 1);
- } else {
- // Check if we have keyframes at in/out points
- updateAnimatedKeyframes(i, param, oldInfo);
}
+ // Check if we have keyframes at in/out points
+ updateAnimatedKeyframes(i, param, oldInfo);
effects[i] = effect.cloneNode().toElement();
} else if (type == QLatin1String("roto-spline")) {
if (!effects.contains(i))
@@ -1856,7 +1855,6 @@ bool ClipItem::updateNormalKeyframes(QDomElement parameter, \
const ItemInfo &oldI
keyframes[keyframepos] = locale.toDouble(keyframe.section('=', 1, 1));
}
-
QMap<int, double>::iterator i = keyframes.end();
int lastPos = -1;
double lastValue = 0;
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index 6700af7..71736aa 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -1380,7 +1380,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event)
ClipItem * item = static_cast <ClipItem *>(m_dragItem);
QDomElement oldEffect = item->selectedEffect().cloneNode().toElement();
if (single == 1) {
- item->insertKeyframe(m_document->getProfileInfo(), \
item->getEffectAtIndex(item->selectedEffectIndex()), \
(item->cropDuration()).frames(m_document->fps()) - 1, -1, true); + \
item->insertKeyframe(m_document->getProfileInfo(), \
item->getEffectAtIndex(item->selectedEffectIndex()), (item->cropStart() + \
item->cropDuration()).frames(m_document->fps()) - 1, -1, true); }
//QString previous = item->keyframes(item->selectedEffectIndex());
item->insertKeyframe(m_document->getProfileInfo(), \
item->getEffectAtIndex(item->selectedEffectIndex()), \
keyFramePos.frames(m_document->fps()), val); @@ -1906,7 +1906,6 @@ bool \
CustomTrackView::itemCollision(AbstractClipItem *item, const ItemInfo &newP
void CustomTrackView::slotRefreshEffects(ClipItem *clip)
{
- // Does not seem used anywhere...
int track = clip->track();
GenTime pos = clip->startPos();
if (!m_timeline->track(track)->removeEffect(pos.seconds(), -1, false)) {
diff --git a/src/timeline/effectmanager.cpp b/src/timeline/effectmanager.cpp
index 75d38d2..bcfb84b 100644
--- a/src/timeline/effectmanager.cpp
+++ b/src/timeline/effectmanager.cpp
@@ -316,8 +316,7 @@ bool EffectManager::editEffect(EffectsParameterList params, int \
duration, bool r
if (params.paramValue(QStringLiteral("kdenlive:sync_in_out")) == \
QLatin1String("1")) { // This effect must sync in / out with parent clip
//params.removeParam(QStringLiteral("sync_in_out"));
- Mlt::Producer prod(m_producer);
- filter->set_in_and_out(prod.get_in(), prod.get_out());
+ filter->set_in_and_out(m_producer.get_int("in"), \
m_producer.get_int("out")); } else {
// Reset in/out properties
filter->set("in", (char*)NULL);
diff --git a/src/timeline/keyframeview.cpp b/src/timeline/keyframeview.cpp
index 93b5028..30586c7 100644
--- a/src/timeline/keyframeview.cpp
+++ b/src/timeline/keyframeview.cpp
@@ -23,7 +23,6 @@ along with this program. If not, see \
<http://www.gnu.org/licenses/>. #include <QPainter>
#include <QAction>
#include <QApplication>
-
#include "klocalizedstring.h"
#include "keyframeview.h"
@@ -142,14 +141,28 @@ void KeyframeView::drawKeyFrames(QRectF br, int length, bool \
active, QPainter *p
Mlt::Animation drawAnim = \
m_keyProperties.get_animation(paramName.toUtf8().constData()); if \
(!drawAnim.is_valid()) continue; QPainterPath path;
- int frame = drawAnim.key_get_frame(0);
+ // Find first key before our clip start, get frame for rect left first
+ int firstKF = qMax(0, drawAnim.previous_key(-m_offset));
+ int lastKF = drawAnim.next_key(duration - m_offset);
+ if (lastKF < duration - m_offset) {
+ lastKF = duration - m_offset;
+ }
+ int frame = firstKF;
double value = \
m_keyProperties.anim_get_double(paramName.toUtf8().constData(), frame, duration - \
m_offset);
QPointF start = keyframePoint(br, frame + m_offset, value, info.factor, \
info.min, info.max); path.moveTo(br.x(), br.bottom());
path.lineTo(br.x(), start.y());
path.lineTo(start);
+ int currentFrame;
painter->setPen(paramName == m_inTimeline ? QColor(Qt::white) : Qt::NoPen);
for(int i = 0; i < drawAnim.key_count(); ++i) {
+ currentFrame = drawAnim.key_get_frame(i);
+ if (currentFrame < firstKF) {
+ continue;
+ }
+ if (currentFrame > lastKF) {
+ break;
+ }
if (active && paramName == m_inTimeline) {
painter->setBrush((drawAnim.key_get_frame(i) == activeKeyframe) ? \
QColor(Qt::red) : QColor(Qt::blue));
painter->drawEllipse(QRectF(transformation.map(start) - h/2, \
transformation.map(start) + h / 2)); @@ -170,10 +183,10 @@ void \
KeyframeView::drawKeyFrames(QRectF br, int length, bool active, QPainter *p case \
mlt_keyframe_smooth: frame = drawAnim.key_get_frame(qMax(i - 1, 0));
value = \
m_keyProperties.anim_get_double(paramName.toUtf8().constData(), frame, duration - \
m_offset);
- QPointF pre = keyframePoint(br, frame, value, info.factor, \
info.min, info.max); + QPointF pre = keyframePoint(br, frame + \
m_offset, value, info.factor, info.min, info.max);
frame = drawAnim.key_get_frame(qMin(i + 2, \
drawAnim.key_count() - 1));
value = \
m_keyProperties.anim_get_double(paramName.toUtf8().constData(), frame, duration - \
m_offset);
- QPointF post = keyframePoint(br, frame, value, info.factor, \
info.min, info.max); + QPointF post = keyframePoint(br, frame \
+ m_offset, value, info.factor, info.min, info.max); QPointF c1 = (end - pre) / 6.0; \
// + start QPointF c2 = (start - post) / 6.0; // + end
double mid = (end.x() - start.x()) / 2;
@@ -832,7 +845,7 @@ bool KeyframeView::loadKeyframes(const QLocale locale, \
QDomElement effect, int c }
attachToEnd = -2;
m_useOffset = effect.attribute(QStringLiteral("kdenlive:sync_in_out")) != \
QLatin1String("1");
- m_offset = effect.attribute("in").toInt() - cropStart;
+ m_offset = effect.attribute(QStringLiteral("in")).toInt() - cropStart;
QDomNodeList params = effect.elementsByTagName(QStringLiteral("parameter"));
for (int i = 0; i < params.count(); ++i) {
QDomElement e = params.item(i).toElement();
@@ -891,9 +904,23 @@ bool KeyframeView::loadKeyframes(const QLocale locale, \
QDomElement effect, int c
void KeyframeView::setOffset(int frames)
{
- if (m_useOffset) {
+ if (!m_keyAnim.is_valid())
+ return;
+ if (m_keyAnim.is_key(-m_offset)) {
+ mlt_keyframe_type type = m_keyAnim.keyframe_type(-m_offset);
+ double value = \
m_keyProperties.anim_get_double(m_inTimeline.toUtf8().constData(), -m_offset, \
duration - m_offset); + m_keyAnim.remove(-m_offset);
+ if (activeKeyframe == -m_offset) {
+ activeKeyframe -= frames;
+ }
+ m_offset -= frames;
+ m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), value, - \
m_offset, duration - m_offset, type); + //addKeyframe(-m_offset, value, type);
+ } else {
m_offset -= frames;
}
+ //double value = \
m_keyProperties.anim_get_double(m_inTimeline.toUtf8().constData(), 0, duration - \
m_offset); + //}
}
// static
@@ -962,6 +989,34 @@ QString KeyframeView::cutAnimation(const QString &animation, int \
start, int dura }
//static
+const QString KeyframeView::addBorderKeyframes(const QString &animation, int start, \
int duration) +{
+ bool modified = false;
+ Mlt::Properties props;
+ props.set("keyframes", animation.toUtf8().constData());
+ props.anim_get_double("keyframes", 0, start+duration);
+ Mlt::Animation anim = props.get_animation("keyframes");
+ if (!anim.is_key(start)) {
+ double value = props.anim_get_double("keyframes", start, start+duration);
+ int previous = anim.previous_key(start);
+ mlt_keyframe_type type = anim.keyframe_type(previous);
+ props.anim_set("keyframes", value, start, start+duration, type);
+ modified = true;
+ }
+ if (!anim.is_key(start+duration)) {
+ double value = props.anim_get_double("keyframes", start+duration, \
start+duration); + int previous = anim.previous_key(start+duration);
+ mlt_keyframe_type type = anim.keyframe_type(previous);
+ props.anim_set("keyframes", value, start+duration, start+duration, type);
+ modified = true;
+ }
+ if (modified) {
+ return anim.serialize_cut();
+ }
+ return animation;
+}
+
+//static
QString KeyframeView::switchAnimation(QString animation, int newPos, int oldPos, int \
newDuration, int oldDuration, bool isRect) {
Mlt::Properties props;
@@ -971,7 +1026,7 @@ QString KeyframeView::switchAnimation(QString animation, int \
newPos, int oldPos, if (anim.is_key(oldPos)) {
// insert new keyframe at start
if (isRect) {
- mlt_rect rect = props.anim_get_rect("keyframes", oldPos);
+ mlt_rect rect = props.anim_get_rect("keyframes", oldPos, oldDuration);
props.anim_set("keyframes", rect, newPos, newDuration, \
anim.keyframe_type(oldPos)); anim.remove(oldPos);
} else {
diff --git a/src/timeline/keyframeview.h b/src/timeline/keyframeview.h
index 2eef776..342b50f 100644
--- a/src/timeline/keyframeview.h
+++ b/src/timeline/keyframeview.h
@@ -97,6 +97,8 @@ public:
static QString switchAnimation(QString animation, int newPos, int oldPos, int \
newDuration, int oldDuration, bool isRect);
/** @brief when loading an animation from a serialized string, check where is \
the first negative keyframe) */ static int checkNegatives(const QString &data, int \
maxDuration); + /** @brief Add keyframes at start / end points if not existing */
+ static const QString addBorderKeyframes(const QString &animation, int start, int \
duration); /** @brief returns true if currently edited parameter name is name */
bool activeParam(const QString &name) const;
/** @brief Sets a temporary offset for drawing keyframes when resizing clip \
start */
diff --git a/src/timeline/track.cpp b/src/timeline/track.cpp
index 32aa837..43ce2ad 100644
--- a/src/timeline/track.cpp
+++ b/src/timeline/track.cpp
@@ -905,9 +905,9 @@ bool Track::editEffect(double start, EffectsParameterList params, \
bool replace) if (!clip) {
return false;
}
- Mlt::Service clipService(clip->get_service());
- EffectManager effect(clipService);
- return effect.editEffect(params, duration, replace);
+ EffectManager effect(*clip.data());
+ bool result = effect.editEffect(params, duration, replace);
+ return result;
}
bool Track::editTrackEffect(EffectsParameterList params, bool replace)
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic