]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Use real MLT position in monitors instead of cached one, preventing race condition...
[kdenlive] / src / renderer.cpp
index c82b41aebabb2a4d0e39746327716c5d663c3136..c9c9611803ee7fa7b4b6c5c08fe21a20908e5fb5 100644 (file)
 
 #include <stdlib.h>
 
+
+
+static void kdenlive_callback(void* /*ptr*/, int level, const char* fmt, va_list vl)
+{
+    if (level > MLT_LOG_ERROR) return;
+    QString error;
+    QApplication::postEvent(qApp->activeWindow() , new MltErrorEvent(error.vsprintf(fmt, vl).simplified()));
+}
+
+
 static void consumer_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?
@@ -134,6 +144,7 @@ void Render::buildConsumer()
     // FIXME: the event object returned by the listen gets leaked...
     m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
     m_mltConsumer->set("rescale", "nearest");
+    mlt_log_set_callback(kdenlive_callback);
 
     QString audioDevice = KdenliveSettings::audiodevicename();
     if (!audioDevice.isEmpty()) {
@@ -149,8 +160,13 @@ void Render::buildConsumer()
     }
 
     QString audioDriver = KdenliveSettings::audiodrivername();
+
+    /*
+    // Disabled because the "auto" detected driver was sometimes wrong
     if (audioDriver.isEmpty())
         audioDriver = KdenliveSettings::autoaudiodrivername();
+    */
+
     if (!audioDriver.isEmpty()) {
         tmp = decodedString(audioDriver);
         m_mltConsumer->set("audio_driver", tmp);
@@ -224,7 +240,7 @@ void Render::seek(GenTime time)
 {
     if (!m_mltProducer)
         return;
-    m_isBlocked = 0;
+    m_isBlocked = false;
     m_mltProducer->seek((int)(time.frames(m_fps)));
     refresh();
 }
@@ -610,25 +626,18 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, bo
             else
                 filePropertyMap["type"] = "video";
 
-            mlt_image_format format = mlt_image_yuv422;
-            int frame_width = 0;
-            int frame_height = 0;
-            //frame->set("rescale.interp", "hyper");
-            frame->set("normalised_height", height);
-            frame->set("normalised_width", width);
+            mlt_image_format format = mlt_image_rgb24a;
+            int frame_width = width;
+            int frame_height = height;
             QPixmap pix(width, height);
-
             uint8_t *data = frame->get_image(format, frame_width, frame_height, 0);
-            uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4);
-            mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height);
-            QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32);
+            QImage image((uchar *)data, frame_width, frame_height, QImage::Format_ARGB32);
 
             if (!image.isNull()) {
                 pix = QPixmap::fromImage(image.rgbSwapped());
             } else
                 pix.fill(Qt::black);
 
-            mlt_pool_release(new_image);
             emit replyGetImage(clipId, pix);
 
         } else if (frame->get_int("test_audio") == 0) {
@@ -1227,6 +1236,17 @@ void Render::seekToFrame(int pos)
     refresh();
 }
 
+void Render::seekToFrameDiff(int diff)
+{
+    //kDebug()<<" *********  RENDER SEEK TO POS";
+    if (!m_mltProducer)
+        return;
+    m_isBlocked = false;
+    resetZoneMode();
+    m_mltProducer->seek(m_mltProducer->position() + diff);
+    refresh();
+}
+
 void Render::askForRefresh()
 {
     // Use a Timer so that we don't refresh too much
@@ -1277,6 +1297,11 @@ GenTime Render::seekPosition() const
     else return GenTime();
 }
 
+int Render::seekFramePosition() const
+{
+    if (m_mltProducer) return (int) m_mltProducer->position();
+    return 0;
+}
 
 const QString & Render::rendererName() const
 {
@@ -2092,7 +2117,7 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
         return success;
     }
 
-    // create filter
+    // find filter
     Mlt::Service service(m_mltProducer->parent().get_service());
 
     Mlt::Tractor tractor(service);
@@ -2138,7 +2163,7 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
         m_isBlocked = false;
         return success;
     }
-
+    mlt_service_lock(service.get_service());
     for (int j = 0; j < params.count(); j++) {
         char *name = decodedString(params.at(j).name());
         char *value = decodedString(params.at(j).value());
@@ -2146,6 +2171,7 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
         delete[] name;
         delete[] value;
     }
+    mlt_service_unlock(service.get_service());
 
     m_isBlocked = false;
     refresh();
@@ -2581,7 +2607,7 @@ bool Render::mltMoveTransition(QString type, int startTrack, int newTrack, int n
     }
     mlt_service_unlock(serv);
     m_isBlocked--;
-    //askForRefresh();
+    refresh();
     //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1);
     return true;
 }
@@ -2591,8 +2617,9 @@ void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b
     if (oldTag == tag) mltUpdateTransitionParams(tag, a_track, b_track, in, out, xml);
     else {
         mltDeleteTransition(oldTag, a_track, b_track, in, out, xml, false);
-        mltAddTransition(tag, a_track, b_track, in, out, xml);
+        mltAddTransition(tag, a_track, b_track, in, out, xml, false);
     }
+    refresh();
     //mltSavePlaylist();
 }
 
@@ -2602,7 +2629,6 @@ void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, G
     mlt_service_lock(serv);
     m_isBlocked++;
 
-
     mlt_service nextservice = mlt_service_get_producer(serv);
     mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
     QString mlt_type = mlt_properties_get(properties, "mlt_type");
@@ -2625,6 +2651,10 @@ void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, G
             QString key;
             mlt_properties transproperties = MLT_TRANSITION_PROPERTIES(tr);
             mlt_properties_set_int(transproperties, "force_track", xml.attribute("force_track").toInt());
+            // update the transition id in case it uses the same MLT service but different Kdenlive id
+            char *tmp = decodedString(xml.attribute("id"));
+            mlt_properties_set(transproperties, "kdenlive_id", tmp);
+            delete[] tmp;
             if (currentBTrack != a_track) {
                 mlt_properties_set_int(properties, "a_track", a_track);
             }
@@ -2871,7 +2901,7 @@ void Render::mltMoveTransparency(int startTime, int endTime, int startTrack, int
 }
 
 
-bool Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool /*do_refresh*/)
+bool Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh)
 {
     if (in >= out) return false;
     QMap<QString, QString> args = mltGetTransitionParamsFromXml(xml);
@@ -2903,7 +2933,7 @@ bool Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in,
     // attach filter to the clip
     field->plant_transition(*transition, a_track, b_track);
     delete[] transId;
-    refresh();
+    if (do_refresh) refresh();
     return true;
 }