]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Fix freeze when making fast play / pause
[kdenlive] / src / renderer.cpp
index 9edc697aa1821c4e4dd3850a72ba85973b47650b..3e18730174c408034b15898a708d2a7d5a72019b 100644 (file)
@@ -71,14 +71,21 @@ static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr
     if (self->analyseAudio) {
         self->showAudio(frame);
     }
-    if (frame.get_double("_speed") == 0.0) {
-        self->emitConsumerStopped();
-    } else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) {
+    if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) {
         self->pause();
         self->emitConsumerStopped();
     }
 }
 
+
+static void consumer_paused(mlt_consumer, Render * self, mlt_frame /*frame_ptr*/)
+{
+    // detect if the producer has finished playing. Is there a better way to do it?
+    if (self->m_isBlocked) return;
+    self->emitConsumerStopped();
+}
+
+
 static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr)
 {
     // detect if the producer has finished playing. Is there a better way to do it?
@@ -94,10 +101,9 @@ static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_
 }
 
 Render::Render(const QString & rendererName, int winid, QString profile, QWidget *parent) :
-    QObject(parent),
+    AbstractRender(rendererName, parent),
     m_isBlocked(0),
     analyseAudio(KdenliveSettings::monitor_audio()),
-    sendFrameForAnalysis(false),
     m_name(rendererName),
     m_mltConsumer(NULL),
     m_mltProducer(NULL),
@@ -241,6 +247,7 @@ void Render::buildConsumer(const QString profileName)
         m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview");
         // FIXME: the event object returned by the listen gets leaked...
         m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+        m_mltConsumer->listen("consumer-sdl-paused", this, (mlt_listener) consumer_paused);
         m_mltConsumer->set("window_id", m_winid);
     }
     m_mltConsumer->set("resize", 1);
@@ -283,6 +290,7 @@ Mlt::Producer *Render::invalidProducer(const QString &id)
 
 int Render::resetProfile(const QString profileName)
 {
+    QString scene = sceneList();
     if (m_mltConsumer) {
         if (m_externalConsumer == KdenliveSettings::external_display()) {
             if (KdenliveSettings::external_display() && m_activeProfile == profileName) return 1;
@@ -303,9 +311,9 @@ int Render::resetProfile(const QString profileName)
         delete m_mltConsumer;
         m_mltConsumer = NULL;
     }
-    QString scene = sceneList();
     int pos = 0;
     double current_fps = m_mltProfile->fps();
+    double current_dar = m_mltProfile->dar();
     delete m_blackClip;
     m_blackClip = NULL;
 
@@ -327,6 +335,7 @@ int Render::resetProfile(const QString profileName)
     m_mltProducer = NULL;
     buildConsumer(profileName);
     double new_fps = m_mltProfile->fps();
+    double new_dar = m_mltProfile->dar();
     if (current_fps != new_fps) {
         // fps changed, we must update the scenelist positions
         scene = updateSceneListFps(current_fps, new_fps, scene);
@@ -334,7 +343,7 @@ int Render::resetProfile(const QString profileName)
     //kDebug() << "//RESET WITHSCENE: " << scene;
     setSceneList(scene, pos);
     // producers have changed (different profile), so reset them...
-    emit refreshDocumentProducers();
+    emit refreshDocumentProducers(new_dar != current_dar);
     /*Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "xml-string", scene.toUtf8().constData());
     m_mltProducer = producer;
     m_blackClip = new Mlt::Producer(*m_mltProfile , "colour", "black");
@@ -607,11 +616,14 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int
         return;
     }
 
-    if (proxyProducer && xml.hasAttribute("proxy_out") && producer->get_out() != xml.attribute("proxy_out").toInt()) {
-        // Proxy file length is different than original clip length, this will corrupt project so disable this proxy clip
-        emit removeInvalidProxy(clipId, true);
-        delete producer;
-        return;
+    if (proxyProducer && xml.hasAttribute("proxy_out")) {
+        producer->set("out", xml.attribute("proxy_out").toInt());
+        if (producer->get_out() != xml.attribute("proxy_out").toInt()) {
+            // Proxy file length is different than original clip length, this will corrupt project so disable this proxy clip
+            emit removeInvalidProxy(clipId, true);
+            delete producer;
+            return;
+        }
     }
 
     if (xml.hasAttribute("force_aspect_ratio")) {
@@ -1015,6 +1027,7 @@ int Render::setSceneList(QString playlist, int position)
                 resource = mlt_properties_get(properties, "mlt_service");
             }
 
+
             for (int trackNb = tractor.count() - 1; trackNb >= 0; --trackNb) {
                 Mlt::Producer trackProducer(tractor.track(trackNb));
                 Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
@@ -1264,7 +1277,6 @@ void Render::stop()
     if (m_mltProducer == NULL) return;
     if (m_mltConsumer && !m_mltConsumer->is_stopped()) {
         kDebug() << "/////////////   RENDER STOPPED: " << m_name;
-        m_isBlocked = true;
         //m_mltConsumer->set("refresh", 0);
         m_mltConsumer->stop();
         // delete m_mltConsumer;
@@ -1310,36 +1322,24 @@ void Render::pause()
     m_mltConsumer->purge();
 }
 
-void Render::switchPlay()
+void Render::switchPlay(bool play)
 {
     if (!m_mltProducer || !m_mltConsumer)
         return;
     if (m_isZoneMode) resetZoneMode();
-    if (m_mltProducer->get_speed() == 0.0) {
+    if (play && m_mltProducer->get_speed() == 0.0) {
         m_isBlocked = false;
         if (m_name == "clip" && m_framePosition == (int) m_mltProducer->get_out()) m_mltProducer->seek(0);
         m_mltProducer->set_speed(1.0);
         m_mltConsumer->set("refresh", 1);
-    } else {
+    } else if (!play) {
         m_isBlocked = true;
         m_mltConsumer->set("refresh", 0);
         m_mltProducer->set_speed(0.0);
         //emit rendererPosition(m_framePosition);
         m_mltProducer->seek(m_framePosition);
-        m_mltConsumer->purge();
-        //kDebug()<<" *********  RENDER PAUSE: "<<m_mltProducer->get_speed();
-        //m_mltConsumer->set("refresh", 0);
-        /*mlt_position position = mlt_producer_position( m_mltProducer->get_producer() );
-        m_mltProducer->set_speed(0);
-        m_mltProducer->seek( position );
-               //m_mltProducer->seek((int) m_framePosition);
-               m_isBlocked = false;*/
+        //m_mltConsumer->purge();
     }
-    /*if (speed == 0.0) {
-    m_mltProducer->seek((int) m_framePosition + 1);
-        m_mltConsumer->purge();
-    }*/
-    //refresh();
 }
 
 void Render::play(double speed)
@@ -1820,7 +1820,7 @@ bool Render::mltUpdateClip(ItemInfo info, QDomElement element, Mlt::Producer *pr
         return false;
     }
     Mlt::Tractor tractor(service);
-    Mlt::Producer trackProducer(tractor.track(info.track));
+    Mlt::Producer trackProducer(tractor.track(tractor.count() - 1 - info.track));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
     int startPos = info.startPos.frames(m_fps);
     int clipIndex = trackPlaylist.get_clip_index_at(startPos);
@@ -2476,7 +2476,6 @@ bool Render::mltAddEffect(Mlt::Service service, EffectsParameterList params, int
     // create filter
     QString tag =  params.paramValue("tag");
     kDebug() << " / / INSERTING EFFECT: " << tag << ", REGI: " << region;
-    if (tag.startsWith("ladspa")) tag = "ladspa";
     char *filterTag = qstrdup(tag.toUtf8().constData());
     char *filterId = qstrdup(params.paramValue("id").toUtf8().constData());
     QHash<QString, QString>::Iterator it;
@@ -3847,12 +3846,12 @@ const QList <Mlt::Producer *> Render::producersList()
         delete tt;
         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);
             Mlt::Producer *nprod = new Mlt::Producer(c->get_parent());
             if (nprod) {
-                if (!nprod->is_blank() && !ids.contains(nprod->get("id"))) {
+                QString prodId = nprod->get("id");
+                if (!prodId.startsWith("slowmotion") && !prodId.isEmpty() && !nprod->is_blank() && !ids.contains(prodId)) {
                     ids.append(nprod->get("id"));
                     prods.append(nprod);
                 } else delete nprod;
@@ -4023,17 +4022,7 @@ void Render::mltDeleteTrack(int ix)
     tractor.removeChild(track);
     //kDebug() << "/////////// RESULT SCENE: \n" << doc.toString();
     setSceneList(doc.toString(), m_framePosition);
-
-    /*    if (m_mltProducer != NULL) {
-            Mlt::Producer parentProd(m_mltProducer->parent());
-            if (parentProd.get_producer() != NULL) {
-                Mlt::Service service(parentProd.get_service());
-                if (service.type() == tractor_type) {
-                    Mlt::Tractor tractor(service);
-                    mltCheckLength(&tractor);
-                }
-            }
-        }*/
+    emit refreshDocumentProducers(false);
 }
 
 
@@ -4162,6 +4151,11 @@ void Render::sendFrameUpdate()
     }
 }
 
+Mlt::Producer* Render::getProducer()
+{
+    return m_mltProducer;
+}
+
 
 #include "renderer.moc"