]> git.sesse.net Git - kdenlive/blobdiff - src/mltdevicecapture.cpp
* Update MLT capture to use the new multi consumer for preview
[kdenlive] / src / mltdevicecapture.cpp
index 8414b074d4476f54e6c4aa70c671ab48a815f0a8..aebcf41c549e9c3abfbfb8f4db494a19fb776921 100644 (file)
@@ -19,9 +19,6 @@
 #include "mltdevicecapture.h"
 #include "kdenlivesettings.h"
 #include "definitions.h"
-//#include "recmonitor.h"
-//#include "renderer.h"
-#include "blackmagic/devices.h"
 
 #include <mlt++/Mlt.h>
 
@@ -90,13 +87,16 @@ MltDeviceCapture::MltDeviceCapture(QString profile, VideoPreviewContainer *surfa
     m_mltProfile(NULL),
     m_showFrameEvent(NULL),
     m_droppedFrames(0),
-    m_livePreview(KdenliveSettings::recording_preview()),
+    m_livePreview(KdenliveSettings::enable_recording_preview()),
     m_captureDisplayWidget(surface),
     m_winid((int) surface->winId())
 {
     if (profile.isEmpty()) profile = KdenliveSettings::current_profile();
     buildConsumer(profile);
     connect(this, SIGNAL(unblockPreview()), this, SLOT(slotPreparePreview()));
+    m_droppedFramesTimer.setSingleShot(false);
+    m_droppedFramesTimer.setInterval(1000);
+    connect(&m_droppedFramesTimer, SIGNAL(timeout()), this, SLOT(slotCheckDroppedFrames()));
 }
 
 MltDeviceCapture::~MltDeviceCapture()
@@ -128,7 +128,8 @@ void MltDeviceCapture::buildConsumer(const QString &profileName)
         }
     }
     setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
-
+    
+  
     if (m_winid == 0) {
         // OpenGL monitor
         m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio");
@@ -164,6 +165,7 @@ void MltDeviceCapture::buildConsumer(const QString &profileName)
 
 void MltDeviceCapture::stop()
 {
+    m_droppedFramesTimer.stop();
     bool isPlaylist = false;
     disconnect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
     m_captureDisplayWidget->stop();
@@ -305,10 +307,22 @@ bool MltDeviceCapture::slotStartPreview(const QString &producer, bool xmlFormat)
         m_mltConsumer = NULL;
         return 0;
     }
+    m_droppedFramesTimer.start();
     connect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
     return 1;
 }
 
+void MltDeviceCapture::slotCheckDroppedFrames()
+{
+    if (m_mltProducer) {
+        int dropped = m_mltProducer->get_int("dropped");
+        if (dropped > m_droppedFrames) {
+            m_droppedFrames = dropped;
+            emit droppedFrames(m_droppedFrames);
+        }
+    }
+}
+
 void MltDeviceCapture::gotCapturedFrame(Mlt::Frame& frame)
 {
     if (m_mltProducer) {
@@ -319,8 +333,8 @@ void MltDeviceCapture::gotCapturedFrame(Mlt::Frame& frame)
         }
     }
     m_frameCount++;
-    if (m_livePreview == 2) return;
-    if (m_livePreview == 0 && (m_frameCount % 10 > 0)) return;
+    if (!m_livePreview) return;
+    //if (m_livePreview == 0 && (m_frameCount % 10 > 0)) return;
     mlt_image_format format = mlt_image_rgb24;
     int width = 0;
     int height = 0;
@@ -384,7 +398,7 @@ void MltDeviceCapture::captureFrame(const QString &path)
     doCapture = 5;
 }
 
-bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &path, const QString &playlist, int livePreview, bool xmlPlaylist)
+bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist)
 {
     stop();
     m_livePreview = livePreview;
@@ -394,12 +408,34 @@ bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &pa
     char *tmp = qstrdup(m_activeProfile.toUtf8().constData());
     m_mltProfile = new Mlt::Profile(tmp);
     delete[] tmp;
-    m_mltProfile->get_profile()->is_explicit = 1;
-    kDebug()<<"-- CREATING CAP: "<<params<<", PATH: "<<path;
+    //m_mltProfile->get_profile()->is_explicit = 1;
+    
+    
+    /*kDebug()<<"-- CREATING CAP: "<<params<<", PATH: "<<path;
     tmp = qstrdup(QString("avformat:" + path).toUtf8().constData());
     m_mltConsumer = new Mlt::Consumer(*m_mltProfile, tmp);
     m_mltConsumer->set("real_time", -KdenliveSettings::mltthreads());
-    delete[] tmp;
+    delete[] tmp;*/
+    
+    m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "multi");
+    if (m_mltConsumer == NULL || !m_mltConsumer->is_valid()) {
+        if (m_mltConsumer) {
+            delete m_mltConsumer;
+            m_mltConsumer = NULL;
+        }
+        return false;
+    }
+    
+    m_winid = (int) m_captureDisplayWidget->winId();
+    
+    // Create multi consumer setup
+    Mlt::Properties *renderProps = new Mlt::Properties;
+    renderProps->set("mlt_service", "avformat");
+    renderProps->set("target", path.toUtf8().constData());
+    renderProps->set("real_time", -KdenliveSettings::mltthreads());
+    renderProps->set("terminate_on_pause", 0);
+    renderProps->set("mlt_profile", m_activeProfile.toUtf8().constData());
+    
 
     QStringList paramList = params.split(" ", QString::SkipEmptyParts);
     char *tmp2;
@@ -408,20 +444,64 @@ bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &pa
         QString value = paramList.at(i).section("=", 1, 1);
         if (value == "%threads") value = QString::number(QThread::idealThreadCount());
         tmp2 = qstrdup(value.toUtf8().constData());
-        m_mltConsumer->set(tmp, tmp2);
+        renderProps->set(tmp, tmp2);
         delete[] tmp;
         delete[] tmp2;
     }
+    mlt_properties consumerProperties = m_mltConsumer->get_properties();
+    mlt_properties_set_data(consumerProperties, "0", renderProps->get_properties(), 0, (mlt_destructor) mlt_properties_close, NULL);
     
-    if (m_mltConsumer == NULL || !m_mltConsumer->is_valid()) {
-        if (m_mltConsumer) {
-            delete m_mltConsumer;
-            m_mltConsumer = NULL;
+    if (m_livePreview) 
+    {
+        // user wants live preview
+        Mlt::Properties *previewProps = new Mlt::Properties;
+        QString videoDriver = KdenliveSettings::videodrivername();
+        if (!videoDriver.isEmpty()) {
+            if (videoDriver == "x11_noaccel") {
+                setenv("SDL_VIDEO_YUV_HWACCEL", "0", 1);
+                videoDriver = "x11";
+            } else {
+                unsetenv("SDL_VIDEO_YUV_HWACCEL");
+            }
         }
-        return false;
+        setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
+        
+        if (m_winid == 0) {
+            // OpenGL monitor
+            previewProps->set("mlt_service", "sdl_audio");
+            previewProps->set("preview_off", 1);
+            previewProps->set("preview_format", mlt_image_rgb24);
+            previewProps->set("terminate_on_pause", 0);
+            m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show);
+        } else {
+            previewProps->set("mlt_service", "sdl_preview");
+            previewProps->set("window_id", m_winid);
+            previewProps->set("terminate_on_pause", 0);
+            //m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) rec_consumer_frame_preview);
+        }
+        //m_mltConsumer->set("resize", 1);
+        previewProps->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData());
+        QString audioDevice = KdenliveSettings::audiodevicename();
+        if (!audioDevice.isEmpty())
+            previewProps->set("audio_device", audioDevice.toUtf8().constData());
+
+        if (!videoDriver.isEmpty())
+            previewProps->set("video_driver", videoDriver.toUtf8().constData());
+
+        QString audioDriver = KdenliveSettings::audiodrivername();
+
+        if (!audioDriver.isEmpty())
+            previewProps->set("audio_driver", audioDriver.toUtf8().constData());
+        
+        previewProps->set("real_time", "0");
+        previewProps->set("mlt_profile", m_activeProfile.toUtf8().constData());
+        mlt_properties_set_data(consumerProperties, "1", previewProps->get_properties(), 0, (mlt_destructor) mlt_properties_close, NULL);
+        //m_showFrameEvent = m_mltConsumer->listen("consumer-frame-render", this, (mlt_listener) rec_consumer_frame_show);
+    }
+    else {
+        
     }
     
-    if (m_livePreview < 2) m_showFrameEvent = m_mltConsumer->listen("consumer-frame-render", this, (mlt_listener) rec_consumer_frame_show);
     tmp = qstrdup(playlist.toUtf8().constData());
     if (xmlPlaylist) {
         // create an xml producer
@@ -446,7 +526,7 @@ bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &pa
         m_mltConsumer = NULL;
         return 0;
     }
-    m_captureDisplayWidget->start();
+    m_droppedFramesTimer.start();
     return 1;
 }