]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Don't crash when wrong sdl driver was selected by user (needs MLT patch):
[kdenlive] / src / renderer.cpp
index a214bf8c2b53a32d1c52e8dc81b1d434c0c389e6..e1207dc21b8521318dbdd2ef3139c476eb5967aa 100644 (file)
@@ -55,7 +55,7 @@ static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr
 
 Render::Render(const QString & rendererName, int winid, int /* extid */, QWidget *parent) :
         QObject(parent),
-        m_isBlocked(1),
+        m_isBlocked(0),
         m_name(rendererName),
         m_mltConsumer(NULL),
         m_mltProducer(NULL),
@@ -550,6 +550,12 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, bo
     producer->set("id", tmp);
     delete[] tmp;
 
+    if (!replaceProducer && xml.hasAttribute("file_hash")) {
+        // Clip  already has all properties
+        emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer);
+        return;
+    }
+
     int height = 50;
     int width = (int)(height  * m_mltProfile->dar());
     QMap < QString, QString > filePropertyMap;
@@ -758,13 +764,13 @@ void Render::initSceneList()
 
 
 /** Create the producer from the MLT XML QDomDocument */
-void Render::setProducer(Mlt::Producer *producer, int position)
+int Render::setProducer(Mlt::Producer *producer, int position)
 {
-    if (m_winid == -1) return;
+    if (m_winid == -1) return -1;
 
     if (m_mltConsumer) {
         m_mltConsumer->stop();
-    } else return;
+    } else return -1;
 
     m_mltConsumer->purge();
 
@@ -785,27 +791,29 @@ void Render::setProducer(Mlt::Producer *producer, int position)
     if (!m_mltProducer || !m_mltProducer->is_valid()) kDebug() << " WARNING - - - - -INVALID PLAYLIST: ";
 
     m_fps = m_mltProducer->get_fps();
-    connectPlaylist();
+    int error = connectPlaylist();
     if (position != -1) {
         m_mltProducer->seek(position);
         emit rendererPosition(position);
     }
     m_isBlocked = false;
+    return error;
 }
 
 
 
 /** Create the producer from the MLT XML QDomDocument */
-void Render::setSceneList(QDomDocument list, int position)
+int Render::setSceneList(QDomDocument list, int position)
 {
-    setSceneList(list.toString(), position);
+    return setSceneList(list.toString(), position);
 }
 
 /** Create the producer from the MLT XML QDomDocument */
-void Render::setSceneList(QString playlist, int position)
+int Render::setSceneList(QString playlist, int position)
 {
-    if (m_winid == -1) return;
+    if (m_winid == -1) return -1;
     m_isBlocked = true;
+    int error;
     qDeleteAll(m_slowmotionProducers.values());
     m_slowmotionProducers.clear();
 
@@ -814,7 +822,7 @@ void Render::setSceneList(QString playlist, int position)
     if (m_mltConsumer == NULL) {
         kWarning() << "///////  ERROR, TRYING TO USE NULL MLT CONSUMER";
         m_isBlocked = false;
-        return;
+        return -1;
     }
 
     if (!m_mltConsumer->is_stopped()) {
@@ -873,12 +881,13 @@ void Render::setSceneList(QString playlist, int position)
     }
 
     kDebug() << "// NEW SCENE LIST DURATION SET TO: " << m_mltProducer->get_playtime();
-    connectPlaylist();
+    error = connectPlaylist();
     fillSlowMotionProducers();
 
     m_isBlocked = false;
     blockSignals(false);
     emit refreshDocumentProducers();
+    return error;
     //kDebug()<<"// SETSCN LST, POS: "<<position;
     //if (position != 0) emit rendererPosition(position);
 }
@@ -963,24 +972,23 @@ double Render::fps() const
     return m_fps;
 }
 
-void Render::connectPlaylist()
+int Render::connectPlaylist()
 {
-    if (!m_mltConsumer) return;
+    if (!m_mltConsumer) return -1;
     //m_mltConsumer->set("refresh", "0");
     m_mltConsumer->connect(*m_mltProducer);
     m_mltProducer->set_speed(0);
-    m_mltConsumer->start();
+    if (m_mltConsumer->start() == -1) {
+        // ARGH CONSUMER BROKEN!!!!
+        KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
+        emit blockMonitors();
+        delete m_mltProducer;
+        m_mltProducer = NULL;
+        return -1;
+    }
     emit durationChanged(m_mltProducer->get_playtime());
+    return 0;
     //refresh();
-    /*
-     if (m_mltConsumer->start() == -1) {
-          KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
-          delete m_mltConsumer;
-          m_mltConsumer = NULL;
-     }
-     else {
-             refresh();
-     }*/
 }
 
 void Render::refreshDisplay()
@@ -1039,14 +1047,13 @@ void Render::start()
         kDebug() << "-----  BROKEN MONITOR: " << m_name << ", RESTART";
         return;
     }
-
     if (m_mltConsumer && m_mltConsumer->is_stopped()) {
         kDebug() << "-----  MONITOR: " << m_name << " WAS STOPPED";
         if (m_mltConsumer->start() == -1) {
             KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
-            delete m_mltConsumer;
-            m_mltConsumer = NULL;
-            return;
+            emit blockMonitors();
+            delete m_mltProducer;
+            m_mltProducer = NULL;
         } else {
             kDebug() << "-----  MONITOR: " << m_name << " REFRESH";
             m_isBlocked = false;
@@ -1075,6 +1082,7 @@ void Render::clear()
 
 void Render::stop()
 {
+    if (m_mltProducer == NULL) return;
     if (m_mltConsumer && !m_mltConsumer->is_stopped()) {
         kDebug() << "/////////////   RENDER STOPPED: " << m_name;
         m_isBlocked = true;
@@ -1222,7 +1230,7 @@ void Render::seekToFrame(int pos)
 void Render::askForRefresh()
 {
     // Use a Timer so that we don't refresh too much
-    m_refreshTimer->start(500);
+    m_refreshTimer->start(300);
 }
 
 void Render::doRefresh()
@@ -1241,6 +1249,22 @@ void Render::refresh()
     }
 }
 
+void Render::setDropFrames(bool show)
+{
+    if (m_mltConsumer) {
+        int dropFrames = 1;
+        if (show == false) dropFrames = 0;
+        m_mltConsumer->stop();
+        m_mltConsumer->set("play.real_time", dropFrames);
+        if (m_mltConsumer->start() == -1) {
+            emit blockMonitors();
+            delete m_mltProducer;
+            m_mltProducer = NULL;
+        }
+
+    }
+}
+
 double Render::playSpeed()
 {
     if (m_mltProducer) return m_mltProducer->get_speed();
@@ -1475,7 +1499,7 @@ void Render::mltCutClip(int track, GenTime position)
             Mlt::Filter *dup = new Mlt::Filter(*m_mltProfile, filter->get("mlt_service"));
             if (dup && dup->is_valid()) {
                 Mlt::Properties entries(filter->get_properties());
-                for (int i = 0;i < entries.count();i++) {
+                for (int i = 0; i < entries.count(); i++) {
                     dup->set(entries.get_name(i), entries.get(i));
                 }
                 dupService.attach(*dup);
@@ -1531,7 +1555,6 @@ bool Render::mltRemoveClip(int track, GenTime position)
         return false;
     }
     m_isBlocked = true;
-    Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
     trackPlaylist.replace_with_blank(clipIndex);
     trackPlaylist.consolidate_blanks(0);
     /*if (QString(clip.parent().get("transparency")).toInt() == 1)
@@ -1723,6 +1746,24 @@ void Render::mltInsertSpace(QMap <int, int> trackClipStartList, QMap <int, int>
     m_mltConsumer->set("refresh", 1);
 }
 
+
+void Render::mltPasteEffects(Mlt::Producer *source, Mlt::Producer *dest)
+{
+    Mlt::Service sourceService(source->get_service());
+    Mlt::Service destService(dest->get_service());
+
+    // move all effects to the correct producer
+    int ct = 0;
+    Mlt::Filter *filter = sourceService.filter(ct);
+    while (filter) {
+        if (filter->get("kdenlive_ix") != 0) {
+            sourceService.detach(*filter);
+            destService.attach(*filter);
+        } else ct++;
+        filter = sourceService.filter(ct);
+    }
+}
+
 int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod)
 {
     m_isBlocked = true;
@@ -1737,16 +1778,22 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
     int clipIndex = trackPlaylist.get_clip_index_at(startPos);
     int clipLength = trackPlaylist.clip_length(clipIndex);
 
-    Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
-    if (!clip.is_valid() || clip.is_blank()) {
+    Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex);
+    if (clip == NULL) {
+        return -1;
+    }
+    if (!clip->is_valid() || clip->is_blank()) {
         // invalid clip
+        delete clip;
         return -1;
     }
-    Mlt::Producer clipparent = clip.parent();
+    Mlt::Producer clipparent = clip->parent();
     if (!clipparent.is_valid() || clipparent.is_blank()) {
         // invalid clip
+        delete clip;
         return -1;
     }
+
     QString serv = clipparent.get("mlt_service");
     QString id = clipparent.get("id");
     //kDebug() << "CLIP SERVICE: " << serv;
@@ -1775,6 +1822,10 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
             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));
+
+        // move all effects to the correct producer
+        mltPasteEffects(clip, cut);
+
         trackPlaylist.insert_at(startPos, *cut, 1);
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
@@ -1796,6 +1847,10 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
             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);
+
+        // move all effects to the correct producer
+        mltPasteEffects(clip, cut);
+
         trackPlaylist.insert_at(startPos, *cut, 1);
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
@@ -1833,12 +1888,17 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
             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 / speed + newDuration).frames(m_fps) - 1));
 
+        // move all effects to the correct producer
+        mltPasteEffects(clip, cut);
+
         trackPlaylist.insert_at(startPos, *cut, 1);
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
 
         mlt_service_unlock(service.get_service());
     }
+
+    delete clip;
     if (clipIndex + 1 == trackPlaylist.count()) mltCheckLength();
     m_isBlocked = false;
     return newLength;
@@ -2165,9 +2225,7 @@ void Render::mltMoveEffect(int track, GenTime position, int oldPos, int newPos)
 bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration)
 {
     m_isBlocked = true;
-
     Mlt::Service service(m_mltProducer->parent().get_service());
-
     Mlt::Tractor tractor(service);
     Mlt::Producer trackProducer(tractor.track(info.track));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
@@ -2187,16 +2245,22 @@ bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration)
         m_isBlocked = false;
         return false;
     }
+    mlt_service_lock(service.get_service());
     int clipIndex = trackPlaylist.get_clip_index_at((int) info.startPos.frames(m_fps));
     //kDebug() << "// SELECTED CLIP START: " << trackPlaylist.clip_start(clipIndex);
     Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex);
     int previousStart = clip->get_in();
     int newDuration = (int) clipDuration.frames(m_fps) - 1;
-    int diff = newDuration - trackPlaylist.clip_length(clipIndex) - 1;
+    int diff = newDuration - (trackPlaylist.clip_length(clipIndex) - 1);
     if (newDuration > clip->get_length()) {
         clip->parent().set("length", newDuration + 1);
         clip->set("length", newDuration + 1);
     }
+    if (newDuration > clip->get_out()) {
+        clip->parent().set_in_and_out(0, newDuration + 1);
+        clip->set_in_and_out(0, newDuration + 1);
+    }
+    delete clip;
     trackPlaylist.resize_clip(clipIndex, previousStart, newDuration + previousStart);
     trackPlaylist.consolidate_blanks(0);
     // skip to next clip
@@ -2218,9 +2282,8 @@ bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration)
             }
         }
     } else trackPlaylist.insert_blank(clipIndex, 0 - diff - 1);
-
     trackPlaylist.consolidate_blanks(0);
-
+    mlt_service_unlock(service.get_service());
 
     if (info.track != 0 && clipIndex == trackPlaylist.count()) mltCheckLength();
     /*if (QString(clip->parent().get("transparency")).toInt() == 1) {
@@ -2277,6 +2340,7 @@ bool Render::mltResizeClipCrop(ItemInfo info, GenTime diff)
         return false;
     }
     int previousStart = clip->get_in();
+    delete clip;
     int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;
     m_isBlocked = true;
     trackPlaylist.resize_clip(clipIndex, previousStart + frameOffset, previousStart + previousDuration + frameOffset);
@@ -2307,6 +2371,7 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff)
         return false;
     }
     int previousStart = clip->get_in();
+    delete clip;
     int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;
     m_isBlocked = true;
     kDebug() << "RESIZE, old start: " << previousStart << ", PREV DUR: " << previousDuration << ", DIFF: " << moveFrame;
@@ -2373,18 +2438,7 @@ void Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod)
     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);
-    }
+    mltPasteEffects(&clipProducer, clip);
 
     trackPlaylist.insert_at(pos, clip, 1);
     mlt_service_unlock(m_mltConsumer->get_service());
@@ -2395,15 +2449,14 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
 {
     m_isBlocked++;
 
-    //m_mltConsumer->set("refresh", 0);
-    mlt_service_lock(m_mltConsumer->get_service());
     Mlt::Service service(m_mltProducer->parent().get_service());
     if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM";
 
     Mlt::Tractor tractor(service);
+    mlt_service_lock(service.get_service());
     Mlt::Producer trackProducer(tractor.track(startTrack));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
-    int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1);
+    int clipIndex = trackPlaylist.get_clip_index_at(moveStart);
     kDebug() << "//////  LOOKING FOR CLIP TO MOVE, INDEX: " << clipIndex;
     bool checkLength = false;
     if (endTrack == startTrack) {
@@ -2413,7 +2466,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             if (!trackPlaylist.is_blank_at(moveEnd)) trackPlaylist.insert_at(moveStart, clipProducer, 1);
             //int ix = trackPlaylist.get_clip_index_at(moveEnd);
             kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
-            mlt_service_unlock(m_mltConsumer->get_service());
+            mlt_service_unlock(service.get_service());
             m_isBlocked--;
             return false;
         } else {
@@ -2430,7 +2483,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
         Mlt::Playlist destTrackPlaylist((mlt_playlist) destTrackProducer.get_service());
         if (!destTrackPlaylist.is_blank_at(moveEnd)) {
             // error, destination is not empty
-            mlt_service_unlock(m_mltConsumer->get_service());
+            mlt_service_unlock(service.get_service());
             m_isBlocked--;
             return false;
         } else {
@@ -2439,7 +2492,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
                 // error, destination is not empty
                 //int ix = trackPlaylist.get_clip_index_at(moveEnd);
                 kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
-                mlt_service_unlock(m_mltConsumer->get_service());
+                mlt_service_unlock(service.get_service());
                 m_isBlocked--;
                 return false;
             }
@@ -2462,18 +2515,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             }
 
             // 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);
-            }
+            mltPasteEffects(&clipProducer, clip);
 
             int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
             destTrackPlaylist.consolidate_blanks(0);
@@ -2485,9 +2527,8 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             else if (newIndex + 1 == destTrackPlaylist.count()) checkLength = true;
         }
     }
-
+    mlt_service_unlock(service.get_service());
     if (checkLength) mltCheckLength();
-    mlt_service_unlock(m_mltConsumer->get_service());
     m_isBlocked--;
     //askForRefresh();
     //m_mltConsumer->set("refresh", 1);
@@ -2500,14 +2541,12 @@ bool Render::mltMoveTransition(QString type, int startTrack, int newTrack, int n
     int new_out = (int)newOut.frames(m_fps) - 1;
     if (new_in >= new_out) return false;
 
-    Mlt::Service service(m_mltProducer->parent().get_service());
-    Mlt::Tractor tractor(service);
-
+    mlt_service serv = m_mltProducer->parent().get_service();
     m_isBlocked++;
-    mlt_service_lock(service.get_service());
+    mlt_service_lock(serv);
     //m_mltConsumer->set("refresh", 0);
 
-    mlt_service serv = m_mltProducer->parent().get_service();
+
     mlt_service nextservice = mlt_service_get_producer(serv);
     mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
     QString mlt_type = mlt_properties_get(properties, "mlt_type");
@@ -2538,7 +2577,7 @@ 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(service.get_service());
+    mlt_service_unlock(serv);
     m_isBlocked--;
     //askForRefresh();
     //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1);
@@ -2557,12 +2596,11 @@ void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b
 
 void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml)
 {
-    Mlt::Service service(m_mltProducer->parent().get_service());
-    Mlt::Tractor tractor(service);
-    mlt_service_lock(service.get_service());
+    mlt_service serv = m_mltProducer->parent().get_service();
+    mlt_service_lock(serv);
     m_isBlocked++;
 
-    mlt_service serv = m_mltProducer->parent().get_service();
+
     mlt_service nextservice = mlt_service_get_producer(serv);
     mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
     QString mlt_type = mlt_properties_get(properties, "mlt_type");
@@ -2606,7 +2644,7 @@ void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, G
         mlt_type = mlt_properties_get(properties, "mlt_type");
         resource = mlt_properties_get(properties, "mlt_service");
     }
-    mlt_service_unlock(service.get_service());
+    mlt_service_unlock(serv);
     m_isBlocked--;
     //askForRefresh();
     //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1);
@@ -2614,15 +2652,15 @@ void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, G
 
 void Render::mltDeleteTransition(QString tag, int /*a_track*/, int b_track, GenTime in, GenTime out, QDomElement /*xml*/, bool /*do_refresh*/)
 {
-    Mlt::Service service(m_mltProducer->parent().get_service());
-    Mlt::Tractor tractor(service);
+    mlt_service serv = m_mltProducer->parent().get_service();
     m_isBlocked++;
-    mlt_service_lock(service.get_service());
+    mlt_service_lock(serv);
 
+    Mlt::Service service(serv);
+    Mlt::Tractor tractor(service);
     Mlt::Field *field = tractor.field();
 
     //if (do_refresh) m_mltConsumer->set("refresh", 0);
-    mlt_service serv = m_mltProducer->parent().get_service();
 
     mlt_service nextservice = mlt_service_get_producer(serv);
     mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
@@ -2649,7 +2687,7 @@ void Render::mltDeleteTransition(QString tag, int /*a_track*/, int b_track, GenT
         mlt_type = mlt_properties_get(properties, "mlt_type");
         resource = mlt_properties_get(properties, "mlt_service");
     }
-    mlt_service_unlock(service.get_service());
+    mlt_service_unlock(serv);
     m_isBlocked--;
     //askForRefresh();
     //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1);
@@ -2659,7 +2697,7 @@ QMap<QString, QString> Render::mltGetTransitionParamsFromXml(QDomElement xml)
 {
     QDomNodeList attribs = xml.elementsByTagName("parameter");
     QMap<QString, QString> map;
-    for (int i = 0;i < attribs.count();i++) {
+    for (int i = 0; i < attribs.count(); i++) {
         QDomElement e = attribs.item(i).toElement();
         QString name = e.attribute("name");
         //kDebug()<<"-- TRANSITION PARAM: "<<name<<" = "<< e.attribute("name")<<" / " << e.attribute("value");
@@ -2681,7 +2719,7 @@ QMap<QString, QString> Render::mltGetTransitionParamsFromXml(QDomElement xml)
             if (values.size() > 0)
                 txtNeu << (int)values[0].toDouble();
             int i = 0;
-            for (i = 0;i < separators.size() && i + 1 < values.size();i++) {
+            for (i = 0; i < separators.size() && i + 1 < values.size(); i++) {
                 txtNeu << separators[i];
                 txtNeu << (int)(values[i+1].toDouble());
             }
@@ -2882,6 +2920,7 @@ void Render::mltSavePlaylist()
 QList <Mlt::Producer *> Render::producersList()
 {
     QList <Mlt::Producer *> prods;
+    if (m_mltProducer == NULL) return prods;
     Mlt::Service service(m_mltProducer->parent().get_service());
     if (service.type() != tractor_type) return prods;
     Mlt::Tractor tractor(service);
@@ -2912,6 +2951,7 @@ QList <Mlt::Producer *> Render::producersList()
 
 void Render::fillSlowMotionProducers()
 {
+    if (m_mltProducer == NULL) return;
     Mlt::Service service(m_mltProducer->parent().get_service());
     if (service.type() != tractor_type) return;
 
@@ -2947,9 +2987,8 @@ void Render::mltInsertTrack(int ix, bool videoTrack)
     blockSignals(true);
     m_isBlocked++;
 
-    m_mltConsumer->set("refresh", 0);
-    mlt_service_lock(m_mltConsumer->get_service());
     Mlt::Service service(m_mltProducer->parent().get_service());
+    mlt_service_lock(service.get_service());
     if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM";
 
     Mlt::Tractor tractor(service);
@@ -3008,15 +3047,16 @@ void Render::mltInsertTrack(int ix, bool videoTrack)
     // Add audio mix transition to last track
     Mlt::Field *field = tractor.field();
     Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, "mix");
-    //transition->set("mlt_service", "mix");
     transition->set("a_track", 1);
     transition->set("b_track", ct);
     transition->set("always_active", 1);
     transition->set("internal_added", 237);
     transition->set("combine", 1);
     field->plant_transition(*transition, 1, ct);
-
-    mlt_service_unlock(m_mltConsumer->get_service());
+    //mlt_service_unlock(m_mltConsumer->get_service());
+    mlt_service_unlock(service.get_service());
+    //tractor.multitrack()->refresh();
+    //tractor.refresh();
     m_isBlocked--;
     blockSignals(false);
 }