]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Fix overwrite clip insert
[kdenlive] / src / renderer.cpp
index 21d15db84bc8a6ecd39f79fd9578de6ea5374b86..0ece7e18ab0ff30ccb7f6e9ee04c0e1d746b0233 100644 (file)
@@ -174,6 +174,7 @@ void Render::buildConsumer(const QString profileName)
     }
     setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
 
+    //m_mltConsumer->set("fullscreen", 1);
 #ifdef Q_WS_MAC
     m_mltConsumer = new Mlt::Consumer(*m_mltProfile , "sdl_audio");
     m_mltConsumer->set("preview_off", 1);
@@ -909,7 +910,7 @@ int Render::setSceneList(QString playlist, int position)
     m_isBlocked = true;
     int error;
 
-    //kWarning() << "//////  RENDER, SET SCENE LIST: " << playlist;
+    kDebug() << "//////  RENDER, SET SCENE LIST: " << playlist;
 
     if (m_mltConsumer == NULL) {
         kWarning() << "///////  ERROR, TRYING TO USE NULL MLT CONSUMER";
@@ -1533,7 +1534,7 @@ void Render::mltCheckLength(Mlt::Tractor *tractor)
     }
 }
 
-int Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *prod)
+int Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *prod, bool overwrite, bool push)
 {
     if (m_mltProducer == NULL) {
         kDebug() << "PLAYLIST NOT INITIALISED //////";
@@ -1561,6 +1562,7 @@ int Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pro
     }
     mlt_service_lock(service.get_service());
     Mlt::Producer trackProducer(tractor.track(info.track));
+    int trackDuration = trackProducer.get_playtime() - 1;
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
     //kDebug()<<"/// INSERT cLIP: "<<info.cropStart.frames(m_fps)<<", "<<info.startPos.frames(m_fps)<<"-"<<info.endPos.frames(m_fps);
 
@@ -1592,9 +1594,22 @@ int Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pro
             return -1;
         }
     }
-
-    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);
+    int cutPos = (int) info.cropStart.frames(m_fps);
+    int insertPos = (int) info.startPos.frames(m_fps);
+    int cutDuration = (int)(info.endPos - info.startPos).frames(m_fps) - 1;
+    Mlt::Producer *clip = prod->cut(cutPos, cutDuration + cutPos);
+    if (overwrite && (insertPos < trackDuration)) {
+        // Replace zone with blanks
+        //trackPlaylist.split_at(insertPos, true);
+        trackPlaylist.remove_region(insertPos, cutDuration + 1);
+        int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
+        trackPlaylist.insert_blank(clipIndex, cutDuration);
+    } else if (push) {
+        trackPlaylist.split_at(insertPos, true);
+        int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
+        trackPlaylist.insert_blank(clipIndex, cutDuration);
+    }
+    int newIndex = trackPlaylist.insert_at(insertPos, clip, 1);
     delete clip;
     /*if (QString(prod->get("transparency")).toInt() == 1)
         mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());*/
@@ -2048,15 +2063,12 @@ int Render::mltChangeClipSpeed(ItemInfo info, ItemInfo speedIndependantInfo, dou
             slowprod->set("id", tmp);
             delete[] tmp;
             // copy producer props
-            tmp = original->parent().get("force_aspect_ratio");
-            if (tmp != NULL) slowprod->set("force_aspect_ratio", tmp);
-            delete[] tmp;
-            tmp = original->parent().get("threads");
-            if (tmp != NULL) slowprod->set("threads", tmp);
-            delete[] tmp;
-            tmp = original->parent().get("video_index");
-            if (tmp != NULL) slowprod->set("video_index", tmp);
-            delete[] tmp;
+            double ar = original->parent().get_double("force_aspect_ratio");
+            if (ar != 0.0) slowprod->set("force_aspect_ratio", ar);
+            int threads = original->parent().get_int("threads");
+            if (threads != 0) slowprod->set("threads", threads);
+            int ix = original->parent().get_int("video_index");
+            if (ix != 0) slowprod->set("video_index", ix);
             m_slowmotionProducers.insert(url, slowprod);
         }
         Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
@@ -2124,15 +2136,12 @@ int Render::mltChangeClipSpeed(ItemInfo info, ItemInfo speedIndependantInfo, dou
             slowprod->set("id", tmp);
             delete[] tmp;
             // copy producer props
-            tmp = original->parent().get("force_aspect_ratio");
-            if (tmp != NULL) slowprod->set("force_aspect_ratio", tmp);
-            delete[] tmp;
-            tmp = original->parent().get("threads");
-            if (tmp != NULL) slowprod->set("threads", tmp);
-            delete[] tmp;
-            tmp = original->parent().get("video_index");
-            if (tmp != NULL) slowprod->set("video_index", tmp);
-            delete[] tmp;
+            double ar = original->parent().get_double("force_aspect_ratio");
+            if (ar != 0.0) slowprod->set("force_aspect_ratio", ar);
+            int threads = original->parent().get_int("threads");
+            if (threads != 0) slowprod->set("threads", threads);
+            int ix = original->parent().get_int("video_index");
+            if (ix != 0) slowprod->set("video_index", ix);
             m_slowmotionProducers.insert(url, slowprod);
         }
         Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
@@ -2739,9 +2748,9 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff)
     return true;
 }
 
-bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod)
+bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod, bool overwrite, bool insert)
 {
-    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod);
+    return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod, overwrite, insert);
 }
 
 
@@ -2785,7 +2794,7 @@ bool Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod)
     return true;
 }
 
-bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod)
+bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod, bool overwrite, bool insert)
 {
     m_isBlocked++;
 
@@ -2804,7 +2813,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
     bool checkLength = false;
     if (endTrack == startTrack) {
         Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
-        if (!trackPlaylist.is_blank_at(moveEnd) || !clipProducer || clipProducer->is_blank()) {
+        if (!overwrite && (!trackPlaylist.is_blank_at(moveEnd) || !clipProducer || clipProducer->is_blank())) {
             // error, destination is not empty
             if (!trackPlaylist.is_blank_at(moveEnd)) trackPlaylist.insert_at(moveStart, clipProducer, 1);
             if (clipProducer) delete clipProducer;
@@ -2815,7 +2824,13 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             return false;
         } else {
             trackPlaylist.consolidate_blanks(0);
+            if (overwrite) {
+                trackPlaylist.remove_region(moveEnd, clipProducer->get_playtime());
+                int clipIndex = trackPlaylist.get_clip_index_at(moveEnd);
+                trackPlaylist.insert_blank(clipIndex, clipProducer->get_playtime() - 1);
+            }
             int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
+            trackPlaylist.consolidate_blanks(1);
             delete clipProducer;
             /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
             mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
@@ -2826,7 +2841,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
     } else {
         Mlt::Producer destTrackProducer(tractor.track(endTrack));
         Mlt::Playlist destTrackPlaylist((mlt_playlist) destTrackProducer.get_service());
-        if (!destTrackPlaylist.is_blank_at(moveEnd)) {
+        if (!overwrite && !destTrackPlaylist.is_blank_at(moveEnd)) {
             // error, destination is not empty
             mlt_service_unlock(service.get_service());
             m_isBlocked--;
@@ -2842,7 +2857,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
                 m_isBlocked--;
                 return false;
             }
-            trackPlaylist.consolidate_blanks(0);
+            trackPlaylist.consolidate_blanks(1);
             destTrackPlaylist.consolidate_blanks(1);
             Mlt::Producer *clip;
             // check if we are moving a slowmotion producer
@@ -2863,6 +2878,12 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             // move all effects to the correct producer
             mltPasteEffects(clipProducer, clip);
 
+            if (overwrite) {
+                destTrackPlaylist.remove_region(moveEnd, clip->get_playtime());
+                int clipIndex = trackPlaylist.get_clip_index_at(moveEnd);
+                trackPlaylist.insert_blank(clipIndex, clip->get_playtime() - 1);
+            }
+
             int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
 
             if (clip == clipProducer) {
@@ -2889,40 +2910,71 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
     return true;
 }
 
+
+QList <int> Render::checkTrackSequence(int track)
+{
+    QList <int> list;
+    Mlt::Service service(m_mltProducer->parent().get_service());
+    if (service.type() != tractor_type) {
+        kWarning() << "// TRACTOR PROBLEM";
+        return list;
+    }
+    Mlt::Tractor tractor(service);
+    mlt_service_lock(service.get_service());
+    Mlt::Producer trackProducer(tractor.track(track));
+    Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+    int clipNb = trackPlaylist.count();
+    //kDebug() << "// PARSING SCENE TRACK: " << t << ", CLIPS: " << clipNb;
+    for (int i = 0; i < clipNb; i++) {
+        Mlt::Producer *c = trackPlaylist.get_clip(i);
+        int pos = trackPlaylist.clip_start(i);
+        if (!list.contains(pos)) list.append(pos);
+        pos += c->get_playtime();
+        if (!list.contains(pos)) list.append(pos);
+        delete c;
+    }
+    return list;
+}
+
 bool Render::mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut)
 {
     int new_in = (int)newIn.frames(m_fps);
     int new_out = (int)newOut.frames(m_fps) - 1;
     if (new_in >= new_out) return false;
 
-    mlt_service serv = m_mltProducer->parent().get_service();
-    m_isBlocked++;
-    mlt_service_lock(serv);
-    //m_mltConsumer->set("refresh", 0);
+    Mlt::Service service(m_mltProducer->parent().get_service());
+    Mlt::Tractor tractor(service);
+    Mlt::Field *field = tractor.field();
 
+    m_isBlocked++;
+    mlt_service_lock(service.get_service());
 
-    mlt_service nextservice = mlt_service_get_producer(serv);
+    mlt_service nextservice = mlt_service_get_producer(service.get_service());
     mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
     QString mlt_type = mlt_properties_get(properties, "mlt_type");
     QString resource = mlt_properties_get(properties, "mlt_service");
     int old_pos = (int)(oldIn.frames(m_fps) + oldOut.frames(m_fps)) / 2;
+    bool found = false;
 
     while (mlt_type == "transition") {
-        mlt_transition tr = (mlt_transition) nextservice;
-        int currentTrack = mlt_transition_get_b_track(tr);
-        int currentIn = (int) mlt_transition_get_in(tr);
-        int currentOut = (int) mlt_transition_get_out(tr);
+        Mlt::Transition transition((mlt_transition) nextservice);
+        int currentTrack = transition.get_b_track();
+        int currentIn = (int) transition.get_in();
+        int currentOut = (int) transition.get_out();
 
         if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) {
-            mlt_transition_set_in_and_out(tr, new_in, new_out);
+            found = true;
             if (newTrack - startTrack != 0) {
-                //kDebug() << "///// TRANSITION CHANGE TRACK. CUrrent (b): " << currentTrack << 'x' << mlt_transition_get_a_track(tr) << ", NEw: " << newTrack << 'x' << newTransitionTrack;
-
-                mlt_properties properties = MLT_TRANSITION_PROPERTIES(tr);
-                mlt_properties_set_int(properties, "a_track", newTransitionTrack);
-                mlt_properties_set_int(properties, "b_track", newTrack);
-                //kDebug() << "set new start & end :" << new_in << new_out<< "TR OFFSET: "<<trackOffset<<", TRACKS: "<<mlt_transition_get_a_track(tr)<<'x'<<mlt_transition_get_b_track(tr);
-            }
+                Mlt::Properties trans_props(transition.get_properties());
+                char *tmp = decodedString(transition.get("mlt_service"));
+                Mlt::Transition new_transition(*m_mltProfile, tmp);
+                delete[] tmp;
+                Mlt::Properties new_trans_props(new_transition.get_properties());
+                new_trans_props.inherit(trans_props);
+                new_transition.set_in_and_out(new_in, new_out);
+                field->disconnect_service(transition);
+                field->plant_transition(new_transition, newTransitionTrack, newTrack);
+            } else transition.set_in_and_out(new_in, new_out);
             break;
         }
         nextservice = mlt_service_producer(nextservice);
@@ -2931,11 +2983,11 @@ bool Render::mltMoveTransition(QString type, int startTrack, int newTrack, int n
         mlt_type = mlt_properties_get(properties, "mlt_type");
         resource = mlt_properties_get(properties, "mlt_service");
     }
-    mlt_service_unlock(serv);
+    mlt_service_unlock(service.get_service());
     m_isBlocked--;
     refresh();
     //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1);
-    return true;
+    return found;
 }
 
 void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml)