]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Fix install location for application icon
[kdenlive] / src / renderer.cpp
index 442450e5c4e0dc40711e896cff262c2a0b080beb..efa71f2d83cafc5ab918a410de67164b72bbd7af 100644 (file)
@@ -174,7 +174,7 @@ int Render::resetProfile() {
     m_mltProfile = NULL;
     buildConsumer();
 
-    kDebug() << "//RESET WITHSCENE: " << scene;
+    //kDebug() << "//RESET WITHSCENE: " << scene;
     setSceneList(scene);
 
     char *tmp = decodedString(scene);
@@ -416,7 +416,7 @@ void Render::slotSplitView(bool doit) {
                 transition->set("b_track", i);
                 transition->set("distort", 1);
                 transition->set("internal_added", "200");
-                char *tmp;
+                const char *tmp;
                 switch (screen) {
                 case 0:
                     tmp = "0,0:50%x50%";
@@ -770,7 +770,7 @@ void Render::setSceneList(QString playlist, int position) {
     if (m_winid == -1) return;
     m_isBlocked = true;
 
-    kWarning() << "//////  RENDER, SET SCENE LIST: " << playlist;
+    //kWarning() << "//////  RENDER, SET SCENE LIST: " << playlist;
 
     if (m_mltConsumer) {
         m_mltConsumer->stop();
@@ -792,7 +792,9 @@ void Render::setSceneList(QString playlist, int position) {
     if (m_blackClip) delete m_blackClip;
     m_blackClip = new Mlt::Producer(*m_mltProfile , "colour", "black");
     m_blackClip->set("id", "black");
-    if (!m_mltProducer || !m_mltProducer->is_valid()) kDebug() << " WARNING - - - - -INVALID PLAYLIST: " << tmp;
+    if (!m_mltProducer || !m_mltProducer->is_valid()) {
+        kDebug() << " WARNING - - - - -INVALID PLAYLIST: " << tmp;
+    }
     m_mltProducer->optimise();
 
     /*if (KdenliveSettings::osdtimecode()) {
@@ -833,55 +835,37 @@ void Render::setSceneList(QString playlist, int position) {
 
 /** Create the producer from the Westley QDomDocument */
 QString Render::sceneList() {
-    KTemporaryFile temp;
-    QString result;
-
-    if (temp.open()) {
-        saveSceneList(temp.fileName());
-        QFile file(temp.fileName());
-        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
-            kWarning() << "++++++++++++++++   CANNOT READ TMP SCENELIST FILE";
-            return QString();
-        }
-        QTextStream in(&file);
-        while (!in.atEnd()) {
-            result.append(in.readLine());
-        }
-    }
-    return result;
-}
-
-void Render::saveSceneList(QString path, QDomElement kdenliveData) {
-
-    char *tmppath = decodedString("westley:" + path);
-    Mlt::Consumer westleyConsumer(*m_mltProfile , tmppath);
+    QString playlist;
+    Mlt::Consumer westleyConsumer(*m_mltProfile , "westley:kdenlive_playlist");
     m_mltProducer->optimise();
-    delete[] tmppath;
     westleyConsumer.set("terminate_on_pause", 1);
     Mlt::Producer prod(m_mltProducer->get_producer());
     bool split = m_isSplitView;
     if (split) slotSplitView(false);
     westleyConsumer.connect(prod);
-    //prod.set("title", "kdenlive document");
     westleyConsumer.start();
     while (!westleyConsumer.is_stopped()) {}
+    playlist = westleyConsumer.get("kdenlive_playlist");
+    if (split) slotSplitView(true);
+    return playlist;
+}
+
+void Render::saveSceneList(QString path, QDomElement kdenliveData) {
+    QFile file(path);
+    QDomDocument doc;
+    doc.setContent(sceneList(), false);
     if (!kdenliveData.isNull()) {
         // add Kdenlive specific tags
-        QFile file(path);
-        QDomDocument doc;
-        doc.setContent(&file, false);
         QDomNode wes = doc.elementsByTagName("westley").at(0);
         wes.appendChild(doc.importNode(kdenliveData, true));
-        file.close();
-        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
-            kWarning() << "//////  ERROR writing to file: " << path;
-            return;
-        }
-        QTextStream out(&file);
-        out << doc.toString();
-        file.close();
     }
-    if (split) slotSplitView(true);
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+        kWarning() << "//////  ERROR writing to file: " << path;
+        return;
+    }
+    QTextStream out(&file);
+    out << doc.toString();
+    file.close();
 }
 
 
@@ -1324,8 +1308,8 @@ void Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pr
     Mlt::Producer *clip = prod->cut((int) info.cropStart.frames(m_fps), (int)(info.endPos - info.startPos + info.cropStart).frames(m_fps) - 1);
     int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1);
 
-    if (QString(prod->get("transparency")).toInt() == 1)
-        mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());
+    /*if (QString(prod->get("transparency")).toInt() == 1)
+        mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());*/
 
     mlt_service_unlock(service.get_service());
 
@@ -1443,8 +1427,8 @@ bool Render::mltRemoveClip(int track, GenTime position) {
     Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
     trackPlaylist.replace_with_blank(clipIndex);
     trackPlaylist.consolidate_blanks(0);
-    if (QString(clip.parent().get("transparency")).toInt() == 1)
-        mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt());
+    /*if (QString(clip.parent().get("transparency")).toInt() == 1)
+        mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt());*/
 
     /* // Display playlist info
     kDebug()<<"////  AFTER";
@@ -1461,7 +1445,7 @@ bool Render::mltRemoveClip(int track, GenTime position) {
     return true;
 }
 
-int Render::mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod) {
+int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod) {
     m_isBlocked = true;
     int newLength = 0;
     Mlt::Service service(m_mltProducer->parent().get_service());
@@ -1470,7 +1454,10 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod)
     Mlt::Tractor tractor(service);
     Mlt::Producer trackProducer(tractor.track(info.track));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
-    int clipIndex = trackPlaylist.get_clip_index_at((int) info.startPos.frames(m_fps));
+    int startPos = info.startPos.frames(m_fps);
+    int clipIndex = trackPlaylist.get_clip_index_at(startPos);
+    int clipLength = trackPlaylist.clip_length(clipIndex);
+
     Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
     QString serv = clip.parent().get("mlt_service");
     QString id = clip.parent().get("id");
@@ -1490,20 +1477,42 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod)
             delete[] tmp;
             m_slowmotionProducers.insert(url, slowprod);
         }
-        Mlt::Producer *cut = slowprod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1);
-        newLength = cut->get_length();
         trackPlaylist.replace_with_blank(clipIndex);
         trackPlaylist.consolidate_blanks(0);
-        trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *cut, 1);
+        // Check that the blank space is long enough for our new duration
+        clipIndex = trackPlaylist.get_clip_index_at(startPos);
+        int blankEnd = trackPlaylist.clip_start(clipIndex) + trackPlaylist.clip_length(clipIndex);
+        Mlt::Producer *cut;
+        if (clipIndex + 1 < trackPlaylist.count() && (startPos + clipLength / speed > blankEnd)) {
+            GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
+            cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)(info.cropStart.frames(m_fps) / speed + maxLength.frames(m_fps) - 1));
+        } else cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)((info.cropStart.frames(m_fps) + clipLength) / speed - 1));
+        trackPlaylist.insert_at(startPos, *cut, 1);
+        clipIndex = trackPlaylist.get_clip_index_at(startPos);
+        newLength = trackPlaylist.clip_length(clipIndex);
         mlt_service_unlock(service.get_service());
     } else if (speed == 1.0) {
         mlt_service_lock(service.get_service());
-        Mlt::Producer *cut = prod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1);
+
         trackPlaylist.replace_with_blank(clipIndex);
-        newLength = cut->get_length();
         trackPlaylist.consolidate_blanks(0);
-        trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *cut, 1);
+
+        // Check that the blank space is long enough for our new duration
+        clipIndex = trackPlaylist.get_clip_index_at(startPos);
+        int blankEnd = trackPlaylist.clip_start(clipIndex) + trackPlaylist.clip_length(clipIndex);
+
+        Mlt::Producer *cut;
+        GenTime oldDuration = GenTime(clipLength, m_fps);
+        GenTime newDuration = oldDuration * oldspeed;
+        if (clipIndex + 1 < trackPlaylist.count() && (info.startPos + newDuration).frames(m_fps) > blankEnd) {
+            GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
+            cut = prod->cut((int)(info.cropStart.frames(m_fps)), (int)(info.cropStart.frames(m_fps) + maxLength.frames(m_fps) - 1));
+        } else cut = prod->cut((int)(info.cropStart.frames(m_fps)), (int)((info.cropStart + newDuration).frames(m_fps)) - 1);
+        trackPlaylist.insert_at(startPos, *cut, 1);
+        clipIndex = trackPlaylist.get_clip_index_at(startPos);
+        newLength = trackPlaylist.clip_length(clipIndex);
         mlt_service_unlock(service.get_service());
+
     } else if (serv == "framebuffer") {
         mlt_service_lock(service.get_service());
         QString url = clip.parent().get("resource");
@@ -1520,15 +1529,29 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod)
             delete[] tmp;
             m_slowmotionProducers.insert(url, slowprod);
         }
-        Mlt::Producer *cut = slowprod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1);
-        newLength = cut->get_length();
         trackPlaylist.replace_with_blank(clipIndex);
         trackPlaylist.consolidate_blanks(0);
-        trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *cut, 1);
+
+        GenTime oldDuration = GenTime(clipLength, m_fps);
+        GenTime newDuration = oldDuration * oldspeed / speed;
+
+        // Check that the blank space is long enough for our new duration
+        clipIndex = trackPlaylist.get_clip_index_at(startPos);
+        int blankEnd = trackPlaylist.clip_start(clipIndex) + trackPlaylist.clip_length(clipIndex);
+
+        Mlt::Producer *cut;
+        if (clipIndex + 1 < trackPlaylist.count() && (info.startPos + newDuration).frames(m_fps) > blankEnd) {
+            GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
+            cut = slowprod->cut((int)(info.cropStart.frames(m_fps)), (int)(info.cropStart.frames(m_fps) + maxLength.frames(m_fps) - 1));
+        } else cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)((info.cropStart / speed + newDuration).frames(m_fps) - 1));
+
+        trackPlaylist.insert_at(startPos, *cut, 1);
+        clipIndex = trackPlaylist.get_clip_index_at(startPos);
+        newLength = trackPlaylist.clip_length(clipIndex);
+
         mlt_service_unlock(service.get_service());
-        kDebug() << "AVFORMAT CLIP!!!:";
     }
-
+    if (clipIndex + 1 == trackPlaylist.count()) mltCheckLength();
     m_isBlocked = false;
     return newLength;
 }
@@ -1870,20 +1893,9 @@ bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration) {
 
     trackPlaylist.consolidate_blanks(0);
 
-    /* // Display playlist info
-    kDebug()<<"////////////  AFTER RESIZE";
-    for (int i = 0; i < trackPlaylist.count(); i++) {
-    int blankStart = trackPlaylist.clip_start(i);
-    int blankDuration = trackPlaylist.clip_length(i) - 1;
-    QString blk;
-    if (trackPlaylist.is_blank(i)) blk = "(blank)";
-    kDebug()<<"CLIP "<<i<<": ("<<blankStart<<"x"<<blankStart + blankDuration<<")"<<blk;
-    }*/
 
-    //tractor.multitrack()->refresh();
-    //tractor.refresh();
     if (info.track != 0 && clipIndex == trackPlaylist.count()) mltCheckLength();
-    if (QString(clip->parent().get("transparency")).toInt() == 1) {
+    /*if (QString(clip->parent().get("transparency")).toInt() == 1) {
         //mltResizeTransparency(previousStart, previousStart, previousStart + newDuration, track, QString(clip->parent().get("id")).toInt());
         mltDeleteTransparency(info.startPos.frames(m_fps), info.track, QString(clip->parent().get("id")).toInt());
         ItemInfo transpinfo;
@@ -1891,7 +1903,7 @@ bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration) {
         transpinfo.endPos = info.startPos + clipDuration;
         transpinfo.track = info.track;
         mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt());
-    }
+    }*/
     m_isBlocked = false;
     return true;
 }
@@ -1955,7 +1967,7 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
         else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1);
     }
     trackPlaylist.consolidate_blanks(0);
-    if (QString(clip->parent().get("transparency")).toInt() == 1) {
+    /*if (QString(clip->parent().get("transparency")).toInt() == 1) {
         //mltResizeTransparency(previousStart, (int) moveEnd.frames(m_fps), (int) (moveEnd + out - in).frames(m_fps), track, QString(clip->parent().get("id")).toInt());
         mltDeleteTransparency(info.startPos.frames(m_fps), info.track, QString(clip->parent().get("id")).toInt());
         ItemInfo transpinfo;
@@ -1963,19 +1975,19 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) {
         transpinfo.endPos = info.startPos + diff + (info.endPos - info.startPos);
         transpinfo.track = info.track;
         mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt());
-    }
+    }*/
     m_isBlocked = false;
     //m_mltConsumer->set("refresh", 1);
     mlt_service_unlock(service.get_service());
     return true;
 }
 
-bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd) {
-    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps));
+bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod) {
+    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod);
 }
 
 
-bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd) {
+bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod) {
     m_isBlocked = true;
 
     m_mltConsumer->set("refresh", 0);
@@ -2003,9 +2015,9 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
         } else {
             trackPlaylist.consolidate_blanks(0);
             int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
-            if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
+            /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
                 mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
-            }
+            }*/
             if (newIndex + 1 == trackPlaylist.count()) checkLength = true;
         }
         //mlt_service_unlock(service.get_service());
@@ -2021,12 +2033,28 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
             trackPlaylist.consolidate_blanks(0);
             destTrackPlaylist.consolidate_blanks(1);
-            int newIndex = destTrackPlaylist.insert_at(moveEnd, clipProducer, 1);
+            Mlt::Producer *clip = prod->cut(clipProducer.get_in(), clipProducer.get_out());
+
+            // move all effects to the correct producer
+            Mlt::Service clipService(clipProducer.get_service());
+            Mlt::Service newClipService(clip->get_service());
+
+            int ct = 0;
+            Mlt::Filter *filter = clipService.filter(ct);
+            while (filter) {
+                if (filter->get("kdenlive_ix") != 0) {
+                    clipService.detach(*filter);
+                    newClipService.attach(*filter);
+                } else ct++;
+                filter = clipService.filter(ct);
+            }
+
+            int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
             destTrackPlaylist.consolidate_blanks(0);
-            if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
+            /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
                 kDebug() << "//////// moving clip transparency";
                 mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
-            }
+            }*/
             if (clipIndex > trackPlaylist.count()) checkLength = true;
             else if (newIndex + 1 == destTrackPlaylist.count()) checkLength = true;
         }
@@ -2183,7 +2211,7 @@ void Render::mltDeleteTransition(QString tag, int a_track, int b_track, GenTime
         mlt_type = mlt_properties_get(properties, "mlt_type");
         resource = mlt_properties_get(properties, "mlt_service");
     }
-    if (do_refresh) m_mltConsumer->set("refresh", 1);
+    //if (do_refresh) m_mltConsumer->set("refresh", 1);
 }
 
 QMap<QString, QString> Render::mltGetTransitionParamsFromXml(QDomElement xml) {
@@ -2373,8 +2401,8 @@ void Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in,
         transition->set_in_and_out((int) in.frames(m_fps), (int) out.frames(m_fps));
     QMap<QString, QString>::Iterator it;
     QString key;
-
-    kDebug() << " ------  ADDING TRANSITION PARAMs: " << args.count();
+    if (xml.attribute("automatic") == "1") transition->set("automatic", 1);
+    //kDebug() << " ------  ADDING TRANSITION PARAMs: " << args.count();
 
     for (it = args.begin(); it != args.end(); ++it) {
         key = it.key();