X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Frenderer.cpp;h=19067517d83c19d6adc93d3f30b1aa62653e231a;hb=56aee6aedeeed3efd10ada8fe3c229eddc01ef05;hp=d141a4f6ace583e4a1570853cb2540c2e733c64e;hpb=a3eee7be24126f5a3458d488f44cd61c66135e17;p=kdenlive diff --git a/src/renderer.cpp b/src/renderer.cpp index d141a4f6..19067517 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -43,11 +43,13 @@ #include #include #include +#include #include #include #include +#include #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();