]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Add animation feature to Slideshow Clip.
[kdenlive] / src / renderer.cpp
index e7aafb3fb704ba1b261453096260cbe656e28611..c60864502164bbdfb5f92886d3aaeb46f670c3cd 100644 (file)
@@ -27,6 +27,7 @@
 #include "kdenlivesettings.h"
 #include "kthumb.h"
 #include "definitions.h"
+#include "slideshowclip.h"
 
 #include <mlt++/Mlt.h>
 
@@ -712,13 +713,31 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int
     Mlt::Frame *frame = producer->get_frame();
 
     if (xml.attribute("type").toInt() == SLIDESHOW) {
-        if (xml.hasAttribute("ttl")) producer->set("ttl", xml.attribute("ttl").toInt());
+        int ttl = xml.hasAttribute("ttl") ? xml.attribute("ttl").toInt() : 0;
+        if (ttl) producer->set("ttl", ttl);
+        if (!xml.attribute("animation").isEmpty()) {
+            Mlt::Filter *filter = new Mlt::Filter(*m_mltProfile, "affine");
+            if (filter && filter->is_valid()) {
+                int cycle = ttl;
+                QString geometry = SlideshowClip::animationToGeometry(xml.attribute("animation"), cycle);
+                if (!geometry.isEmpty()) {
+                    if (xml.attribute("animation").contains("low-pass")) {
+                        Mlt::Filter *blur = new Mlt::Filter(*m_mltProfile, "boxblur");
+                        if (blur && blur->is_valid())
+                            producer->attach(*blur);
+                    }
+                    filter->set("transition.geometry", geometry.toUtf8().data());
+                    filter->set("transition.cycle", cycle);
+                    producer->attach(*filter);
+                }
+            }
+        }
         if (xml.attribute("fade") == "1") {
             // user wants a fade effect to slideshow
             Mlt::Filter *filter = new Mlt::Filter(*m_mltProfile, "luma");
             if (filter && filter->is_valid()) {
-                if (xml.hasAttribute("ttl")) filter->set("period", xml.attribute("ttl").toInt() - 1);
-                if (xml.hasAttribute("luma_duration") && !xml.attribute("luma_duration").isEmpty()) filter->set("luma.out", xml.attribute("luma_duration").toInt());
+                if (ttl) filter->set("cycle", ttl);
+                if (xml.hasAttribute("luma_duration") && !xml.attribute("luma_duration").isEmpty()) filter->set("duration", xml.attribute("luma_duration").toInt());
                 if (xml.hasAttribute("luma_file") && !xml.attribute("luma_file").isEmpty()) {
                     char *tmp = decodedString(xml.attribute("luma_file"));
                     filter->set("luma.resource", tmp);
@@ -728,8 +747,7 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int
                         filter->set("luma.softness", (double) soft / 100.0);
                     }
                 }
-                Mlt::Service clipService(producer->get_service());
-                clipService.attach(*filter);
+                producer->attach(*filter);
             }
         }
         if (xml.attribute("crop") == "1") {
@@ -2267,10 +2285,11 @@ bool Render::mltRemoveTrackEffect(int track, QString index, bool updateIndex)
     Mlt::Service clipService(trackPlaylist.get_service());
 
     m_isBlocked = true;
+    mlt_service_lock(service.get_service());
     int ct = 0;
     Mlt::Filter *filter = clipService.filter(ct);
     while (filter) {
-        if ((index == "-1" && strcmp(filter->get("kdenlive_id"), ""))  || QString(filter->get("kdenlive_ix")) == index) {
+        if ((index == "-1" && strcmp(filter->get("kdenlive_id"), ""))  || filter->get_int("kdenlive_ix") == index.toInt()) {
             if (clipService.detach(*filter) == 0) success = true;
         } else if (updateIndex) {
             // Adjust the other effects index
@@ -2280,6 +2299,7 @@ bool Render::mltRemoveTrackEffect(int track, QString index, bool updateIndex)
         filter = clipService.filter(ct);
     }
     m_isBlocked = false;
+    mlt_service_unlock(service.get_service());
     refresh();
     return success;
 }
@@ -2314,10 +2334,11 @@ bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool up
 
 //    if (tag.startsWith("ladspa")) tag = "ladspa";
     m_isBlocked = true;
+    mlt_service_lock(service.get_service());
     int ct = 0;
     Mlt::Filter *filter = clipService.filter(ct);
     while (filter) {
-        if ((index == "-1" && strcmp(filter->get("kdenlive_id"), ""))  || QString(filter->get("kdenlive_ix")) == index) {// && filter->get("kdenlive_id") == id) {
+        if ((index == "-1" && strcmp(filter->get("kdenlive_id"), ""))  || filter->get_int("kdenlive_ix") == index.toInt()) {// && filter->get("kdenlive_id") == id) {
             if (clipService.detach(*filter) == 0) success = true;
             //kDebug()<<"Deleted filter id:"<<filter->get("kdenlive_id")<<", ix:"<<filter->get("kdenlive_ix")<<", SERVICE:"<<filter->get("mlt_service");
         } else if (updateIndex) {
@@ -2328,6 +2349,7 @@ bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool up
         filter = clipService.filter(ct);
     }
     m_isBlocked = false;
+    mlt_service_unlock(service.get_service());
     if (doRefresh) refresh();
     return success;
 }
@@ -2359,7 +2381,6 @@ bool Render::mltAddEffect(int track, GenTime position, EffectsParameterList para
     }
 
     Mlt::Service clipService(clip->get_service());
-    m_isBlocked = true;
     int duration = clip->get_playtime();
     if (doRefresh) {
         // Check if clip is visible in monitor
@@ -2376,6 +2397,9 @@ bool Render::mltAddEffect(Mlt::Service service, EffectsParameterList params, int
     const int filter_ix = params.paramValue("kdenlive_ix").toInt();
     const QString region =  params.paramValue("region");
     int ct = 0;
+    m_isBlocked = true;
+    mlt_service_lock(service.get_service());
+
     Mlt::Filter *filter = service.filter(ct);
     while (filter) {
         if (filter->get_int("kdenlive_ix") == filter_ix) {
@@ -2399,6 +2423,7 @@ bool Render::mltAddEffect(Mlt::Service service, EffectsParameterList params, int
             filter = service.filter(ct);
         }
         m_isBlocked = false;
+        mlt_service_unlock(service.get_service());
         if (doRefresh) refresh();
         return true;
     }
@@ -2512,6 +2537,7 @@ bool Render::mltAddEffect(Mlt::Service service, EffectsParameterList params, int
         } else {
             kDebug() << "filter is NULL";
             m_isBlocked = false;
+            mlt_service_unlock(service.get_service());
             return false;
         }
         params.removeParam("kdenlive_id");
@@ -2560,6 +2586,7 @@ bool Render::mltAddEffect(Mlt::Service service, EffectsParameterList params, int
         service.attach(*filter);
     }
     m_isBlocked = false;
+    mlt_service_unlock(service.get_service());
     if (doRefresh) refresh();
     return true;
 }
@@ -2578,7 +2605,7 @@ bool Render::mltEditTrackEffect(int track, EffectsParameterList params)
 
     Mlt::Filter *filter = clipService.filter(ct);
     while (filter) {
-        if (QString(filter->get("kdenlive_ix")) == index) {
+        if (filter->get_int("kdenlive_ix") == index.toInt()) {
             break;
         }
         ct++;
@@ -2621,7 +2648,8 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
         // This is a keyframe effect, to edit it, we remove it and re-add it.
         bool success = mltRemoveEffect(track, position, index, false);
         if (!success) kDebug() << "// ERROR Removing effect : " << index;
-        success = mltAddTrackEffect(track, params);
+        if (position < GenTime()) success = mltAddTrackEffect(track, params);
+        else success = mltAddEffect(track, position, params);
         if (!success) kDebug() << "// ERROR Adding effect : " << index;
         return success;
     }
@@ -2663,7 +2691,7 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
 
     Mlt::Filter *filter = clipService.filter(ct);
     while (filter) {
-        if (QString(filter->get("kdenlive_ix")) == index) {
+        if (filter->get_int("kdenlive_ix") == index.toInt()) {
             break;
         }
         ct++;