From: Jean-Baptiste Mardelle Date: Sat, 22 Dec 2012 14:09:57 +0000 (+0100) Subject: Improve OpenGL with external preview X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=4c0b2ea8678ba5f62b1091f6146c2fc207dfff31;p=kdenlive Improve OpenGL with external preview --- diff --git a/src/renderer.cpp b/src/renderer.cpp index 2bc6cca6..849dd873 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -61,7 +61,8 @@ static void kdenlive_callback(void* /*ptr*/, int level, const char* fmt, va_list } -static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr) +//static +void Render::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? self->emitFrameNumber(); @@ -93,29 +94,34 @@ static void consumer_paused(mlt_consumer, Render * self, mlt_frame frame_ptr) else self->emitConsumerStopped(); }*/ - -static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr) +// static +void Render::consumer_gl_frame_show(mlt_consumer consumer, Render * self, mlt_frame frame_ptr) { // detect if the producer has finished playing. Is there a better way to do it? + if (self->externalConsumer && !self->analyseAudio && !self->sendFrameForAnalysis) { + emit self->rendererPosition((int) mlt_consumer_position(consumer)); + return; + } Mlt::Frame frame(frame_ptr); if (frame.get_double("_speed") == 0) self->emitConsumerStopped(); else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { self->pause(); self->emitConsumerStopped(true); } - self->showFrame(frame); + emit self->mltFrameReceived(new Mlt::Frame(frame_ptr)); } Render::Render(Kdenlive::MONITORID rendererName, int winid, QString profile, QWidget *parent) : AbstractRender(rendererName, parent), requestedSeekPosition(SEEK_INACTIVE), + showFrameSemaphore(1), + externalConsumer(false), m_name(rendererName), m_mltConsumer(NULL), m_mltProducer(NULL), m_mltProfile(NULL), m_showFrameEvent(NULL), m_pauseEvent(NULL), - m_externalConsumer(false), m_isZoneMode(false), m_isLoopMode(false), m_isSplitView(false), @@ -135,6 +141,7 @@ Render::Render(Kdenlive::MONITORID rendererName, int winid, QString profile, QWi connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); connect(this, SIGNAL(multiStreamFound(const QString &,QList,QList,stringMap)), this, SLOT(slotMultiStreamProducerFound(const QString &,QList,QList,stringMap))); connect(this, SIGNAL(checkSeeking()), this, SLOT(slotCheckSeeking())); + connect(this, SIGNAL(mltFrameReceived(Mlt::Frame *)), this, SLOT(showFrame(Mlt::Frame *)), Qt::UniqueConnection); } Render::~Render() @@ -229,18 +236,20 @@ void Render::buildConsumer(const QString &profileName) mlt_log_set_callback(kdenlive_callback); } if (m_mltConsumer->is_valid()) { - m_externalConsumer = true; + externalConsumer = true; m_mltConsumer->set("terminate_on_pause", 0); m_mltConsumer->set("deinterlace_method", "onefield"); m_mltConsumer->set("rescale", "nearest"); m_mltConsumer->set("buffer", "1"); m_mltConsumer->set("real_time", KdenliveSettings::mltthreads()); } - if (m_mltConsumer && m_mltConsumer->is_valid()) return; + if (m_mltConsumer && m_mltConsumer->is_valid()) { + return; + } KMessageBox::information(qApp->activeWindow(), i18n("Your project's profile %1 is not compatible with the blackmagic output card. Please see supported profiles below. Switching to normal video display.", m_mltProfile->description())); } } - m_externalConsumer = false; + externalConsumer = false; QString videoDriver = KdenliveSettings::videodrivername(); if (!videoDriver.isEmpty()) { if (videoDriver == "x11_noaccel") { @@ -265,7 +274,7 @@ void Render::buildConsumer(const QString &profileName) if (m_mltConsumer) { m_mltConsumer->set("terminate_on_pause", 0); m_mltConsumer->set("deinterlace_method", "onefield"); - m_externalConsumer = true; + externalConsumer = true; } } } @@ -341,7 +350,7 @@ int Render::resetProfile(const QString &profileName, bool dropSceneList) { m_refreshTimer.stop(); if (m_mltConsumer) { - if (m_externalConsumer == KdenliveSettings::external_display()) { + if (externalConsumer == KdenliveSettings::external_display()) { if (KdenliveSettings::external_display() && m_activeProfile == profileName) return 1; QString videoDriver = KdenliveSettings::videodrivername(); QString currentDriver = m_mltConsumer->get("video_driver"); @@ -416,7 +425,7 @@ void Render::seek(int time) requestedSeekPosition = time; m_mltProducer->seek(time); //m_mltConsumer->purge(); - if (m_paused && !m_externalConsumer) { + if (m_paused && !externalConsumer) { refresh(); } } @@ -1800,24 +1809,26 @@ void Render::exportCurrentFrame(KUrl url, bool /*notify*/) } -void Render::showFrame(Mlt::Frame& frame) +void Render::showFrame(Mlt::Frame* frame) { int currentPos = m_mltConsumer->position(); if (currentPos == requestedSeekPosition) requestedSeekPosition = SEEK_INACTIVE; emit rendererPosition(currentPos); - if (frame.is_valid()) { + if (frame->is_valid()) { mlt_image_format format = mlt_image_rgb24a; int width = 0; int height = 0; - const uchar* image = frame.get_image(format, width, height); + const uchar* image = frame->get_image(format, width, height); 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 (analyseAudio) showAudio(frame); - if (sendFrameForAnalysis && frame.get_frame()->convert_image) { + if (sendFrameForAnalysis) { emit frameUpdated(qimage.rgbSwapped()); } - } + } else delete frame; + showFrameSemaphore.release(); emit checkSeeking(); } @@ -1847,6 +1858,7 @@ void Render::showAudio(Mlt::Frame& frame) if (!frame.is_valid() || frame.get_int("test_audio") != 0) { return; } + mlt_audio_format audio_format = mlt_audio_s16; //FIXME: should not be hardcoded.. int freq = 48000; diff --git a/src/renderer.h b/src/renderer.h index 835b3c20..4008a2c6 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -44,6 +44,7 @@ #include #include #include +#include class QTimer; class QPixmap; @@ -294,7 +295,6 @@ Q_OBJECT public: void updatePreviewSettings(); void setDropFrames(bool show); QString updateSceneListFps(double current_fps, double new_fps, QString scene); - void showFrame(Mlt::Frame&); void showAudio(Mlt::Frame&); @@ -328,7 +328,13 @@ Q_OBJECT public: /** @brief Frame rendering is handeled by Kdenlive, don't show video through SDL display */ void disablePreview(bool disable); int requestedSeekPosition; + QSemaphore showFrameSemaphore; + bool externalConsumer; +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); + private: /** @brief The name of this renderer. @@ -342,7 +348,6 @@ private: Mlt::Event *m_showFrameEvent; Mlt::Event *m_pauseEvent; double m_fps; - bool m_externalConsumer; /** @brief True if we are playing a zone. * @@ -402,7 +407,7 @@ private slots: void processFileProperties(); /** @brief A clip with multiple video streams was found, ask what to do. */ void slotMultiStreamProducerFound(const QString path, QList audio_list, QList video_list, stringMap data); - + void showFrame(Mlt::Frame *); void slotCheckSeeking(); signals: @@ -446,9 +451,10 @@ signals: * * Used in Mac OS X. */ void showImageSignal(QImage); - void showAudioSignal(const QByteArray &); + void showAudioSignal(const QVector &); void addClip(const KUrl &, stringMap); void checkSeeking(); + void mltFrameReceived(Mlt::Frame *); public slots: