]> git.sesse.net Git - kdenlive/commitdiff
Integrate with the required MLT hooks for getting Movit to work.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 13 Mar 2014 21:16:48 +0000 (22:16 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 13 Mar 2014 21:16:48 +0000 (22:16 +0100)
src/clipmanager.h
src/main.cpp
src/recmonitor.cpp
src/renderer.cpp
src/renderer.h

index 172d0d527e722e1e6265e8017d31b38fc424e91a..0dba867ff0452e89ef2024c571c5a31cd4e072d9 100644 (file)
@@ -126,6 +126,7 @@ Q_OBJECT public:
     /** @brief remove a clip id from the queue list. */
     void stopThumbs(const QString &id);
     void projectTreeThumbReady(const QString &id, int frame, const QImage &img, int type);
+    QGLWidget *getMainContext() const { return m_mainGLContext; }
 
 #if KDE_IS_VERSION(4,5,0)
     KImageCache* pixmapCache;
index 54dfd83dedccd26bc6cba555257dbe830f29ab27..d791a58f752a173c7ae07f78e7bf309d3ff3fccc 100644 (file)
@@ -30,6 +30,8 @@
 
 int main(int argc, char *argv[])
 {
+    QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
+
     KAboutData aboutData(QByteArray("kdenlive"), QByteArray("kdenlive"),
                          ki18n("Kdenlive"), VERSION,
                          ki18n("An open source video editor."),
index de9f07fa4fade8ec82bc78e8a0b6962b3318f51a..956d3e6dbb6e07c41443a26cba4b7570054dce01 100644 (file)
@@ -44,6 +44,7 @@
 #include <QFile>
 #include <QDir>
 #include <QDesktopWidget>
+#include <QPainter>
 
 
 RecMonitor::RecMonitor(Kdenlive::MonitorId name, MonitorManager *manager, QWidget *parent) :
index d141a4f6ace583e4a1570853cb2540c2e733c64e..19067517d83c19d6adc93d3f30b1aa62653e231a 100644 (file)
 #include <QString>
 #include <QApplication>
 #include <QtConcurrentRun>
+#include <QGLWidget>
 
 #include <cstdlib>
 #include <cstdarg>
 
 #include <QDebug>
+#include <assert.h>
 
 #define SEEK_INACTIVE (-1)
 
@@ -81,6 +83,32 @@ void Render::consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_pt
     }
 }
 
+void Render::consumer_thread_started(mlt_consumer, Render * self, mlt_frame)
+{
+    pthread_t thr = pthread_self();
+    if (self->m_renderThreadGLContexts.count(thr) == 0) {
+        QGLWidget *ctx = new QGLWidget(0, self->m_mainGLContext);
+        ctx->resize(0, 0);
+        self->m_renderThreadGLContexts.insert(thr, ctx);
+    }
+    self->m_renderThreadGLContexts[thr]->makeCurrent();
+    self->m_glslManager->fire_event("init glsl");
+    if (!self->m_glslManager->get_int("glsl_supported")) {
+        QMessageBox::critical(NULL, i18n("Movit failed initialization"),
+                              i18n("Initialization of OpenGL filters failed. Exiting."));
+        qApp->quit();
+    }
+}
+
+void Render::consumer_thread_stopped(mlt_consumer, Render * self, mlt_frame)
+{
+    pthread_t thr = pthread_self();
+    assert(self->m_renderThreadGLContexts.count(thr) != 0);
+    self->m_renderThreadGLContexts[thr]->makeCurrent();
+    delete self->m_renderThreadGLContexts[thr];
+    self->m_renderThreadGLContexts.remove(thr);
+}
+
 /*
 static void consumer_paused(mlt_consumer, Render * self, mlt_frame frame_ptr)
 {
@@ -121,6 +149,8 @@ Render::Render(Kdenlive::MonitorId rendererName, int winid, QString profile, QWi
     m_mltProducer(NULL),
     m_mltProfile(NULL),
     m_showFrameEvent(NULL),
+    m_consumerThreadStartedEvent(NULL),
+    m_consumerThreadStoppedEvent(NULL),
     m_pauseEvent(NULL),
     m_isZoneMode(false),
     m_isLoopMode(false),
@@ -166,6 +196,8 @@ void Render::closeMlt()
     m_requestList.clear();
     m_infoThread.waitForFinished();
     delete m_showFrameEvent;
+    delete m_consumerThreadStartedEvent;
+    delete m_consumerThreadStoppedEvent;
     delete m_pauseEvent;
     delete m_mltConsumer;
     delete m_mltProducer;
@@ -292,7 +324,9 @@ void Render::buildConsumer(const QString &profileName)
                 m_mltConsumer->set("scrub_audio", 1);
                 m_mltConsumer->set("preview_off", 1);
                 m_mltConsumer->set("audio_buffer", 512);
-                m_mltConsumer->set("preview_format", mlt_image_rgb24a);
+                m_mltConsumer->set("mlt_image_format", "glsl");
+                m_consumerThreadStartedEvent = m_mltConsumer->listen("consumer-thread-started", this, (mlt_listener) consumer_thread_started);
+                m_consumerThreadStoppedEvent = m_mltConsumer->listen("consumer-thread-stopped", this, (mlt_listener) consumer_thread_stopped);
             }
             m_mltConsumer->set("buffer", "1");
             m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show);
@@ -1260,6 +1294,10 @@ void Render::startConsumer() {
         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."));
         if (m_showFrameEvent) delete m_showFrameEvent;
         m_showFrameEvent = NULL;
+        if (m_consumerThreadStartedEvent) delete m_consumerThreadStartedEvent;
+        m_consumerThreadStartedEvent = NULL;
+        if (m_consumerThreadStoppedEvent) delete m_consumerThreadStoppedEvent;
+        m_consumerThreadStoppedEvent = NULL;
         if (m_pauseEvent) delete m_pauseEvent;
         m_pauseEvent = NULL;
         delete m_mltConsumer;
@@ -1825,12 +1863,12 @@ int Render::seekFramePosition() const
 
 void Render::emitFrameUpdated(Mlt::Frame& frame)
 {
-    mlt_image_format format = mlt_image_rgb24;
+    mlt_image_format format = mlt_image_rgb24a;
     int width = 0;
     int height = 0;
     const uchar* image = frame.get_image(format, width, height);
-    QImage qimage(width, height, QImage::Format_RGB888);  //Format_ARGB32_Premultiplied);
-    memcpy(qimage.scanLine(0), image, width * height * 3);
+    QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied);
+    memcpy(qimage.scanLine(0), image, width * height * 4);
     emit frameUpdated(qimage);
 }
 
@@ -1908,18 +1946,26 @@ void Render::showFrame(Mlt::Frame* frame)
     if (currentPos == requestedSeekPosition) requestedSeekPosition = SEEK_INACTIVE;
     emit rendererPosition(currentPos);
     if (frame->is_valid()) {
-        mlt_image_format format = mlt_image_rgb24;
+        mlt_image_format format = mlt_image_glsl_texture;
         int width = 0;
         int height = 0;
-        const uchar* image = frame->get_image(format, width, height);
-        QImage qimage(width, height, QImage::Format_RGB888); //Format_ARGB32_Premultiplied);
-        memcpy(qimage.scanLine(0), image, width * height * 3);
-        if (analyseAudio) showAudio(*frame);
-        delete frame;
-        emit showImageSignal(qimage);
-        if (sendFrameForAnalysis) {
-            emit frameUpdated(qimage);
-        }
+        m_GLContext->makeCurrent();
+        frame->set("movit.convert.use_texture", 1);
+        const uint8_t* image = frame->get_image(format, width, height);
+        const GLuint* texnum = (GLuint *)image;
+        if (format == mlt_image_glsl_texture) {
+          emit showImageSignal(*texnum);
+          delete frame;
+        } else {
+          QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied);
+          memcpy(qimage.scanLine(0), image, width * height * 4);
+          if (analyseAudio) showAudio(*frame);
+          delete frame;
+          emit showImageSignal(qimage);
+          if (sendFrameForAnalysis) {
+              emit frameUpdated(qimage);
+          }
+       }
     } else delete frame;
     showFrameSemaphore.release();
     emit checkSeeking();
index 96e23dce9f03ef61c5927832d5d4c585cdbf24c4..43be7b8bffcb280978738ee5a017160a84281df3 100644 (file)
@@ -357,6 +357,8 @@ class Render: public AbstractRender
 protected:
     static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr);
     static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr);
+    static void consumer_thread_started(mlt_consumer, Render * self, mlt_frame frame_ptr);
+    static void consumer_thread_stopped(mlt_consumer, Render * self, mlt_frame frame_ptr);
     
 private:
 
@@ -369,6 +371,8 @@ private:
     Mlt::Producer * m_mltProducer;
     Mlt::Profile *m_mltProfile;
     Mlt::Event *m_showFrameEvent;
+    Mlt::Event *m_consumerThreadStartedEvent;
+    Mlt::Event *m_consumerThreadStoppedEvent;
     Mlt::Event *m_pauseEvent;
     double m_fps;
 
@@ -402,6 +406,7 @@ private:
     bool m_isActive;
     QGLWidget *m_mainGLContext;
     QGLWidget *m_GLContext;
+    QMap<pthread_t, QGLWidget *> m_renderThreadGLContexts;
     Mlt::Filter* m_glslManager;
 
     void closeMlt();