+
+ if (effect.attribute("tag") == "volume" || effect.attribute("tag") == "brightness") {
+ if (effect.attribute("id") == "fadeout" || effect.attribute("id") == "fade_to_black") {
+ int end = (duration() + cropStart()).frames(m_fps);
+ int start = end;
+ if (effect.attribute("id") == "fadeout") {
+ if (m_effectList.hasEffect(QString(), "fade_to_black") == -1) {
+ start -= EffectsList::parameter(effect, "in").toInt();
+ } else {
+ QDomElement fadeout = m_effectList.getEffectByTag(QString(), "fade_to_black");
+ start -= EffectsList::parameter(fadeout, "out").toInt() - EffectsList::parameter(fadeout, "in").toInt();
+ }
+ } else if (effect.attribute("id") == "fade_to_black") {
+ if (m_effectList.hasEffect(QString(), "fadeout") == -1) {
+ start -= EffectsList::parameter(effect, "in").toInt();
+ } else {
+ QDomElement fadeout = m_effectList.getEffectByTag(QString(), "fadeout");
+ start -= EffectsList::parameter(fadeout, "out").toInt() - EffectsList::parameter(fadeout, "in").toInt();
+ }
+ }
+ EffectsList::setParameter(effect, "in", QString::number(start));
+ EffectsList::setParameter(effect, "out", QString::number(end));
+ } else if (effect.attribute("id") == "fadein" || effect.attribute("id") == "fade_from_black") {
+ int start = cropStart().frames(m_fps);
+ int end = start;
+ if (effect.attribute("id") == "fadein") {
+ if (m_effectList.hasEffect(QString(), "fade_from_black") == -1)
+ end += EffectsList::parameter(effect, "out").toInt();
+ else
+ end += EffectsList::parameter(m_effectList.getEffectByTag(QString(), "fade_from_black"), "out").toInt();
+ } else if (effect.attribute("id") == "fade_from_black") {
+ if (m_effectList.hasEffect(QString(), "fadein") == -1)
+ end += EffectsList::parameter(effect, "out").toInt();
+ else
+ end += EffectsList::parameter(m_effectList.getEffectByTag(QString(), "fadein"), "out").toInt();
+ }
+ EffectsList::setParameter(effect, "in", QString::number(start));
+ EffectsList::setParameter(effect, "out", QString::number(end));
+ }
+ }
+}
+
+bool ClipItem::checkKeyFrames() {
+ bool clipEffectsModified = false;
+ for (int ix = 0; ix < m_effectList.count(); ix ++) {
+ QString kfr = keyframes(ix);
+ if (!kfr.isEmpty()) {
+ const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts);
+ QStringList newKeyFrames;
+ bool cutKeyFrame = false;
+ bool modified = false;
+ int lastPos = -1;
+ double lastValue = -1;
+ int start = m_cropStart.frames(m_fps);
+ int end = (m_cropStart + m_cropDuration).frames(m_fps);
+ foreach(const QString &str, keyframes) {
+ int pos = str.section(':', 0, 0).toInt();
+ double val = str.section(':', 1, 1).toDouble();
+ if (pos - start < 0) {
+ // a keyframe is defined before the start of the clip
+ cutKeyFrame = true;
+ } else if (cutKeyFrame) {
+ // create new keyframe at clip start, calculate interpolated value
+ if (pos > start) {
+ int diff = pos - lastPos;
+ double ratio = (double)(start - lastPos) / diff;
+ double newValue = lastValue + (val - lastValue) * ratio;
+ newKeyFrames.append(QString::number(start) + ':' + QString::number(newValue));
+ modified = true;
+ }
+ cutKeyFrame = false;
+ }
+ if (!cutKeyFrame) {
+ if (pos > end) {
+ // create new keyframe at clip end, calculate interpolated value
+ int diff = pos - lastPos;
+ if (diff != 0) {
+ double ratio = (double)(end - lastPos) / diff;
+ double newValue = lastValue + (val - lastValue) * ratio;
+ newKeyFrames.append(QString::number(end) + ':' + QString::number(newValue));
+ modified = true;
+ }
+ break;
+ } else {
+ newKeyFrames.append(QString::number(pos) + ':' + QString::number(val));
+ }
+ }
+ lastPos = pos;
+ lastValue = val;
+ }
+ if (modified) {
+ // update KeyFrames
+ setKeyframes(ix, newKeyFrames.join(";"));
+ clipEffectsModified = true;
+ }
+ }
+ }
+ return clipEffectsModified;