]> git.sesse.net Git - kdenlive/commitdiff
several keyframe effect fixes
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 21 Jun 2008 13:39:44 +0000 (13:39 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 21 Jun 2008 13:39:44 +0000 (13:39 +0000)
svn path=/branches/KDE4/; revision=2261

effects/volume.xml
src/clipitem.cpp
src/clipitem.h
src/customtrackview.cpp
src/effectslist.cpp
src/effectslist.h
src/renderer.cpp
src/trackview.cpp

index 0a8ca0027a092de767956e04f87869c8c47bd498..1eaa6e0cb04cd02084a73f7d98c941c979ba6edf 100644 (file)
@@ -1,5 +1,5 @@
 <!DOCTYPE kpartgui>
-<effect tag="volume">
+<effect tag="volume" id="volume">
        <name>Volume</name>
        <description>Adjust audio volume with keyframes</description>
        <author>Dan Dennedy</author>
index 1792e636f0d60ffcc06f076d3b123a03e261e50c..fd9caa6bf4a18658f3f90a274f4fa6325919e114 100644 (file)
@@ -104,6 +104,32 @@ int ClipItem::selectedEffectIndex() const {
     return m_selectedEffect;
 }
 
+void ClipItem::initEffect(QDomElement effect) {
+    // the kdenlive_ix int is used to identify an effect in mlt's playlist, should
+    // not be changed
+    if (effect.attribute("kdenlive_ix").toInt() == 0)
+        effect.setAttribute("kdenlive_ix", QString::number(effectsCounter()));
+    // init keyframes if required
+    QDomNodeList params = effect.elementsByTagName("parameter");
+    for (int i = 0; i < params.count(); i++) {
+        QDomElement e = params.item(i).toElement();
+        if (!e.isNull() && e.attribute("type") == "keyframe") {
+            double max = e.attribute("max").toDouble();
+            double min = e.attribute("min").toDouble();
+            double def = e.attribute("default").toDouble();
+            double factor = e.attribute("factor", "1").toDouble();
+
+            // Effect has a keyframe type parameter, we need to set the values
+            if (e.attribute("keyframes").isEmpty()) {
+                // no keyframes defined, set up 2 keyframes (start and end) with default value.
+                e.setAttribute("keyframes", QString::number(m_cropStart.frames(m_fps)) + ":" + QString::number(100 * def / (max - min)) + ";" + QString::number((m_cropStart + m_cropDuration).frames(m_fps)) + ":" + QString::number(100 * def / (max - min)));
+                //kDebug() << "///// EFFECT KEYFRAMES INITED: " << e.attribute("keyframes");
+                break;
+            }
+        }
+    }
+}
+
 
 void ClipItem::setSelectedEffect(int ix) {
     //if (ix == m_selectedEffect) return;
@@ -114,24 +140,25 @@ void ClipItem::setSelectedEffect(int ix) {
         QDomElement e = params.item(i).toElement();
         if (!e.isNull() && e.attribute("type") == "keyframe") {
             m_keyframes.clear();
-            int max = e.attribute("max").toInt();
-            int min = e.attribute("min").toInt();
-            int def = e.attribute("default").toInt();
+            double max = e.attribute("max").toDouble();
+            double min = e.attribute("min").toDouble();
+            double def = e.attribute("default").toDouble();
             double factor = e.attribute("factor", "1").toDouble();
 
             // Effect has a keyframe type parameter, we need to set the values
-            if (e.attribute("keyframes").isEmpty()) {
+            /*if (e.attribute("keyframes").isEmpty()) {
                 // no keyframes defined, set up 2 keyframes (start and end) with default value.
                 m_keyframes[m_cropStart.frames(m_fps)] = 100 * def / (max - min);
                 m_keyframes[(m_cropStart + m_cropDuration).frames(m_fps)] = 100 * def / (max - min);
-            } else {
-                // parse keyframes
-                QStringList keyframes = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
-                foreach(QString str, keyframes) {
-                    int pos = str.section(":", 0, 0).toInt();
-                    double val = str.section(":", 1, 1).toDouble();
-                    m_keyframes[pos] = val;
-                }
+            e.setAttribute("keyframes", QString::number(m_cropStart.frames(m_fps)) + ":" + QString::number(100 * def / (max - min)) + ";" + QString::number((m_cropStart + m_cropDuration).frames(m_fps)) + ":" + QString::number(100 * def / (max - min)));
+            } else {*/
+            // parse keyframes
+            QStringList keyframes = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
+            foreach(QString str, keyframes) {
+                int pos = str.section(":", 0, 0).toInt();
+                double val = str.section(":", 1, 1).toDouble();
+                m_keyframes[pos] = val;
+                //}
             }
             update();
             return;
@@ -784,7 +811,17 @@ QMap <QString, QString> ClipItem::addEffect(QDomElement effect, bool animate) {
     for (int i = 0; i < params.count(); i++) {
         QDomElement e = params.item(i).toElement();
         if (!e.isNull()) {
-                       double f = e.attribute("factor", "1").toDouble();
+            if (e.attribute("type") == "keyframe") {
+                effectParams["keyframes"] = e.attribute("keyframes");
+                effectParams["min"] = e.attribute("min");
+                effectParams["max"] = e.attribute("max");
+                effectParams["factor"] = e.attribute("factor", "1");
+                effectParams["starttag"] = e.attribute("starttag", "start");
+                effectParams["endtag"] = e.attribute("endtag", "end");
+            }
+
+            double f = e.attribute("factor", "1").toDouble();
+
             if (f == 1) {
                 effectParams[e.attribute("name")] = e.attribute("value");
                 // check if it is a fade effect
index 51c6e44c557e19d4600449c43bc3621de337e80c..e091916af28e3d43efaad556b361f59a0c20a85e 100644 (file)
@@ -85,6 +85,7 @@ public:
     void updateKeyframeEffect();
     QDomElement selectedEffect();
     int selectedEffectIndex() const;
+    void initEffect(QDomElement effect);
 
 protected:
     //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
index 19e94e7f407d0bf1dde25a22adbd37856e516366..0c514f1560fe557478ee30074a76e1dd87d85bea 100644 (file)
@@ -610,10 +610,7 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *item = (ClipItem *)itemList.at(i);
-            // the kdenlive_ix int is used to identify an effect in mlt's playlist, should
-            // not be changed
-            if (effect.attribute("kdenlive_ix").toInt() == 0)
-                effect.setAttribute("kdenlive_ix", QString::number(item->effectsCounter()));
+            item->initEffect(effect);
             AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), effect, true);
             m_commandStack->push(command);
         }
index c5b7d6219ebeefa42eff8ff798c17103e9db1a5e..c9586801a364bbdd46f0c1bb9f8870c70e31a8c7 100644 (file)
@@ -113,6 +113,15 @@ QString EffectsList::getInfo(QString effectName) {
     return info;
 }
 
+bool EffectsList::hasKeyFrames(QDomElement effect) {
+    QDomNodeList params = effect.elementsByTagName("parameter");
+    for (int i = 0; i < params.count(); i++) {
+        QDomElement e = params.item(i).toElement();
+        if (e.attribute("type") == "keyframe") return true;
+    }
+    return false;
+}
+
 // static
 void EffectsList::setParameter(QDomElement effect, QString name, QString value) {
     QDomNodeList params = effect.elementsByTagName("parameter");
index e7f6d28b9c24a8b8560733f859c2c3b926af953f..462e283ff74fd7a4b1caa492346a9c42a3cf6582 100644 (file)
@@ -38,7 +38,7 @@ public:
     QStringList effectNames();
     QString getInfo(QString effectName);
     QMap <QString, QString> effect(const QString & name);
-
+    static bool hasKeyFrames(QDomElement effect);
     static void setParameter(QDomElement effect, QString name, QString value);
 };
 
index b2d00f2920b78bf20e46622623ce4bdf76800d39..ea55281673234ec16aa2db193d5c4c52909f37db 100644 (file)
@@ -1150,17 +1150,20 @@ void Render::mltAddEffect(int track, GenTime position, QMap <QString, QString> a
     if (!kfr.isEmpty()) {
         QStringList keyFrames = kfr.split(";", QString::SkipEmptyParts);
         kDebug() << "// ADDING KEYFRAME EFFECT: " << args.value("keyframes");
-        char *starttag = decodedString(args.value("starttag"));
+        char *starttag = decodedString(args.value("starttag", "start"));
         char *endtag = decodedString(args.value("endtag", "end"));
         kDebug() << "// ADDING KEYFRAME TAGS: " << starttag << ", " << endtag;
         int duration = clip->get_playtime();
-        int max = args.value("max").toInt();
-        int min = args.value("min").toInt();
+        double max = args.value("max").toDouble();
+        double min = args.value("min").toDouble();
         double factor = args.value("factor", "1").toDouble();
         args.remove("starttag");
         args.remove("endtag");
         args.remove("keyframes");
-               int offset = 0;
+        args.remove("min");
+        args.remove("max");
+        args.remove("factor");
+        int offset = 0;
         for (int i = 0; i < keyFrames.size() - 1; ++i) {
             Mlt::Filter *filter = new Mlt::Filter(*m_mltProfile, filterTag);
             filter->set("kdenlive_id", filterId);
@@ -1183,7 +1186,7 @@ void Render::mltAddEffect(int track, GenTime position, QMap <QString, QString> a
             filter->set(starttag, QString::number((min + y1 * (max - min) / 100.0) / factor).toUtf8().data());
             filter->set(endtag, QString::number((min + y2 * (max - min) / 100.0) / factor).toUtf8().data());
             clipService.attach(*filter);
-                       offset = 1;
+            offset = 1;
         }
         delete[] starttag;
         delete[] endtag;
index 32e162d68fed5a8b49f46ada784d0ecd23aebda5..2d217bdab9e3084ec405e7dd5621f608a6875fce 100644 (file)
@@ -207,8 +207,8 @@ void TrackView::parseDocument(QDomDocument doc) {
                             QDomElement e = params.item(i).toElement();
                             if (!e.isNull() && e.attribute("tag") == paramName) {
                                 if (e.attribute("type") == "double") {
-                                    QString factor = e.attribute("factor");
-                                    if (!factor.isEmpty()) {
+                                    QString factor = e.attribute("factor", "1");
+                                    if (factor != "1") {
                                         double val = paramValue.toDouble() * factor.toDouble();
                                         paramValue = QString::number(val);
                                     }
@@ -353,6 +353,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) {
                 for (QDomNode n2 = elem.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
                     QDomElement effect = n2.toElement();
                     if (effect.tagName() == "filter") {
+                        kDebug() << " * * * * * * * * * * ** CLIP EFF FND  * * * * * * * * * * *";
                         // add effect to clip
                         QString effecttag;
                         QString effectid;
@@ -363,11 +364,9 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) {
                             QDomElement effectparam = n3.toElement();
                             if (effectparam.attribute("name") == "tag") {
                                 effecttag = effectparam.text();
-                            }
-                            if (effectparam.attribute("name") == "kdenlive_id") {
+                            } else if (effectparam.attribute("name") == "kdenlive_id") {
                                 effectid = effectparam.text();
-                            }
-                            if (effectparam.attribute("name") == "kdenlive_ix") {
+                            } else if (effectparam.attribute("name") == "kdenlive_ix") {
                                 effectindex = effectparam.text();
                             }
                         }
@@ -379,6 +378,75 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) {
                         clipeffect.setAttribute("kdenlive_ix", effectindex);
                         QDomNodeList clipeffectparams = clipeffect.childNodes();
 
+                        if (MainWindow::videoEffects.hasKeyFrames(clipeffect)) {
+                            kDebug() << " * * * * * * * * * * ** CLIP EFF WITH KFR FND  * * * * * * * * * * *";
+                            // effect is key-framable, read all effects to retrieve keyframes
+                            double min;
+                            double max;
+                            double factor;
+                            QString starttag;
+                            QString endtag;
+                            QDomNodeList params = clipeffect.elementsByTagName("parameter");
+                            for (int i = 0; i < params.count(); i++) {
+                                QDomElement e = params.item(i).toElement();
+                                if (e.attribute("type") == "keyframe") {
+                                    starttag = e.attribute("starttag", "start");
+                                    endtag = e.attribute("endtag", "end");
+                                    min = e.attribute("min").toDouble();
+                                    max = e.attribute("max").toDouble();
+                                    factor = e.attribute("factor", "1").toDouble();
+                                    break;
+                                }
+                            }
+                            QString keyframes;
+                            int effectin = effect.attribute("in").toInt();
+                            int effectout = effect.attribute("out").toInt();
+                            double startvalue;
+                            double endvalue;
+                            for (QDomNode n3 = effect.firstChild(); !n3.isNull(); n3 = n3.nextSibling()) {
+                                // parse effect parameters
+                                QDomElement effectparam = n3.toElement();
+                                if (effectparam.attribute("name") == starttag)
+                                    startvalue = effectparam.text().toDouble() * factor / (max - min) * 100;
+                                if (effectparam.attribute("name") == endtag)
+                                    endvalue = effectparam.text().toDouble() * factor / (max - min) * 100;
+                            }
+                            // add first keyframe
+                            keyframes.append(QString::number(in + effectin) + ":" + QString::number(startvalue) + ";" + QString::number(in + effectout) + ":" + QString::number(endvalue) + ";");
+                            QDomNode lastParsedEffect;
+                            n2 = n2.nextSibling();
+                            bool continueParsing = true;
+                            for (; !n2.isNull() && continueParsing; n2 = n2.nextSibling()) {
+                                // parse all effects
+                                QDomElement kfreffect = n2.toElement();
+                                int effectout = kfreffect.attribute("out").toInt();
+
+                                for (QDomNode n4 = kfreffect.firstChild(); !n4.isNull(); n4 = n4.nextSibling()) {
+                                    // parse effect parameters
+                                    QDomElement subeffectparam = n4.toElement();
+                                    if (subeffectparam.attribute("name") == "kdenlive_ix" && subeffectparam.text() != effectindex) {
+                                        //We are not in the same effect, stop parsing
+                                        lastParsedEffect = n2.previousSibling();
+                                        continueParsing = false;
+                                        break;
+                                    } else if (subeffectparam.attribute("name") == endtag) {
+                                        endvalue = subeffectparam.text().toDouble() * factor / (max - min) * 100;
+                                        break;
+                                    }
+                                }
+                                if (continueParsing) keyframes.append(QString::number(in + effectout) + ":" + QString::number(endvalue) + ";");
+                            }
+
+                            params = clipeffect.elementsByTagName("parameter");
+                            for (int i = 0; i < params.count(); i++) {
+                                QDomElement e = params.item(i).toElement();
+                                if (e.attribute("type") == "keyframe") e.setAttribute("keyframes", keyframes);
+                            }
+                            if (!continueParsing) {
+                                n2 = lastParsedEffect;
+                            }
+                        }
+
                         // adjust effect parameters
                         for (QDomNode n3 = effect.firstChild(); !n3.isNull(); n3 = n3.nextSibling()) {
                             // parse effect parameters