From 60d534a5d6d3472625430e4ffda2f654f7aec0c3 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Mon, 9 Aug 2010 04:42:30 +0000 Subject: [PATCH] Update scopes using a frame image from the consumer-frame-show event handler instead of requesting it from the producer with possibly an undesirable seek as a side effect. svn path=/trunk/kdenlive/; revision=4691 --- CMakeLists.txt | 2 +- src/abstractscopewidget.cpp | 12 +++++++++--- src/abstractscopewidget.h | 5 ++++- src/histogram.cpp | 4 ++-- src/histogram.h | 2 +- src/renderer.cpp | 17 +++++++++++++---- src/renderer.h | 3 ++- src/rgbparade.cpp | 4 ++-- src/rgbparade.h | 2 +- src/vectorscope.cpp | 4 ++-- src/vectorscope.h | 2 +- src/waveform.cpp | 4 ++-- src/waveform.h | 2 +- 13 files changed, 41 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4df7fdc8..3fb30492 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,4 +60,4 @@ add_subdirectory(titles) add_subdirectory(po) add_subdirectory(man) -configure_file(${CMAKE_SOURCE_DIR}/kdenlive-config.h.cmake kdenlive-config.h @ONLY) \ No newline at end of file +configure_file(${CMAKE_SOURCE_DIR}/kdenlive-config.h.cmake kdenlive-config.h @ONLY) diff --git a/src/abstractscopewidget.cpp b/src/abstractscopewidget.cpp index d38d6b4c..f0317534 100644 --- a/src/abstractscopewidget.cpp +++ b/src/abstractscopewidget.cpp @@ -68,7 +68,7 @@ AbstractScopeWidget::AbstractScopeWidget(Monitor *projMonitor, Monitor *clipMoni b &= connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint))); b &= connect(m_activeRender, SIGNAL(rendererPosition(int)), this, SLOT(slotRenderZoneUpdated())); - b &= connect(m_activeRender, SIGNAL(frameUpdated(int)), this, SLOT(slotRenderZoneUpdated())); + b &= connect(m_activeRender, SIGNAL(frameUpdated(QImage)), this, SLOT(slotRenderZoneUpdated(QImage))); b &= connect(this, SIGNAL(signalHUDRenderingFinished(uint,uint)), this, SLOT(slotHUDRenderingFinished(uint,uint))); b &= connect(this, SIGNAL(signalScopeRenderingFinished(uint,uint)), this, SLOT(slotScopeRenderingFinished(uint,uint))); @@ -122,7 +122,7 @@ void AbstractScopeWidget::prodScopeThread() // See http://doc.qt.nokia.com/latest/qtconcurrentrun.html#run about // running member functions in a thread - m_threadScope = QtConcurrent::run(this, &AbstractScopeWidget::renderScope, m_accelFactorScope); + m_threadScope = QtConcurrent::run(this, &AbstractScopeWidget::renderScope, m_accelFactorScope, m_scopeImage); qDebug() << "Scope thread started in " << widgetName(); @@ -328,7 +328,7 @@ void AbstractScopeWidget::slotActiveMonitorChanged(bool isClipMonitor) m_activeRender = (isClipMonitor) ? m_clipMonitor->render : m_projMonitor->render; b &= connect(m_activeRender, SIGNAL(rendererPosition(int)), this, SLOT(slotRenderZoneUpdated())); - b &= connect(m_activeRender, SIGNAL(frameUpdated(int)), this, SLOT(slotRenderZoneUpdated())); + b &= connect(m_activeRender, SIGNAL(frameUpdated(QImage)), this, SLOT(slotRenderZoneUpdated(QImage))); Q_ASSERT(b); // Update the scope for the new monitor. @@ -357,6 +357,12 @@ void AbstractScopeWidget::slotRenderZoneUpdated() } } +void AbstractScopeWidget::slotRenderZoneUpdated(QImage frame) +{ + m_scopeImage = frame; + slotRenderZoneUpdated(); +} + void AbstractScopeWidget::slotResetRealtimeFactor(bool realtimeChecked) { if (!realtimeChecked) { diff --git a/src/abstractscopewidget.h b/src/abstractscopewidget.h index 9514db5c..415c8bc2 100644 --- a/src/abstractscopewidget.h +++ b/src/abstractscopewidget.h @@ -125,7 +125,7 @@ protected: /** @brief Scope renderer. Must emit signalScopeRenderingFinished() when calculation has finished, to allow multi-threading. accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */ - virtual QImage renderScope(uint accelerationFactor) = 0; + virtual QImage renderScope(uint accelerationFactor, QImage) = 0; /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */ virtual QImage renderBackground(uint accelerationFactor) = 0; @@ -193,6 +193,8 @@ private: QFuture m_threadScope; QFuture m_threadBackground; + QImage m_scopeImage; + bool initialDimensionUpdateDone; void prodHUDThread(); void prodScopeThread(); @@ -206,6 +208,7 @@ private slots: void slotActiveMonitorChanged(bool isClipMonitor); void customContextMenuRequested(const QPoint &pos); void slotRenderZoneUpdated(); + void slotRenderZoneUpdated(QImage); void slotHUDRenderingFinished(uint mseconds, uint accelerationFactor); void slotScopeRenderingFinished(uint mseconds, uint accelerationFactor); void slotBackgroundRenderingFinished(uint mseconds, uint accelerationFactor); diff --git a/src/histogram.cpp b/src/histogram.cpp index 52935f31..64c307a8 100644 --- a/src/histogram.cpp +++ b/src/histogram.cpp @@ -65,7 +65,7 @@ QImage Histogram::renderHUD(uint) emit signalHUDRenderingFinished(0, 1); return QImage(); } -QImage Histogram::renderScope(uint accelFactor) +QImage Histogram::renderScope(uint accelFactor, QImage qimage) { QTime start = QTime::currentTime(); start.start(); @@ -75,7 +75,7 @@ QImage Histogram::renderScope(uint accelFactor) | (ui->cbG->isChecked() ? 1 : 0) * HistogramGenerator::ComponentG | (ui->cbB->isChecked() ? 1 : 0) * HistogramGenerator::ComponentB; - QImage histogram = m_histogramGenerator->calculateHistogram(m_scopeRect.size(), m_activeRender->extractFrame(m_activeRender->seekFramePosition()), + QImage histogram = m_histogramGenerator->calculateHistogram(m_scopeRect.size(), qimage, componentFlags, m_aUnscaled->isChecked(), accelFactor); emit signalScopeRenderingFinished(start.elapsed(), accelFactor); diff --git a/src/histogram.h b/src/histogram.h index 1c653e9a..2b1f1eb9 100644 --- a/src/histogram.h +++ b/src/histogram.h @@ -34,7 +34,7 @@ private: bool isScopeDependingOnInput() const; bool isBackgroundDependingOnInput() const; QImage renderHUD(uint accelerationFactor); - QImage renderScope(uint accelerationFactor); + QImage renderScope(uint accelerationFactor, QImage); QImage renderBackground(uint accelerationFactor); Ui::Histogram_UI *ui; diff --git a/src/renderer.cpp b/src/renderer.cpp index 26791b5b..3f5cf863 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -65,6 +65,8 @@ static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr #endif self->emitFrameNumber(mlt_frame_get_position(frame_ptr)); + if (frame_ptr->convert_image) + self->emitFrameUpdated(frame); if (frame.get_double("_speed") == 0.0) { self->emitConsumerStopped(); } else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { @@ -1438,12 +1440,19 @@ const QString & Render::rendererName() const return m_name; } +void Render::emitFrameUpdated(Mlt::Frame& frame) +{ + 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_ARGB32); + memcpy(qimage.bits(), image, width * height * 4); + emit frameUpdated(qimage); +} + void Render::emitFrameNumber(double position) { - if (position == m_framePosition) { - emit frameUpdated((int) position); - return; - } m_framePosition = position; emit rendererPosition((int) position); } diff --git a/src/renderer.h b/src/renderer.h index 3c0e98dc..3b51dc7a 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -161,6 +161,7 @@ Q_OBJECT public: GenTime seekPosition() const; int seekFramePosition() const; + void emitFrameUpdated(Mlt::Frame&); void emitFrameNumber(double position); void emitConsumerStopped(); @@ -344,7 +345,7 @@ signals: * Used in Mac OS X. */ void showImageSignal(QImage); /** @brief The renderer refreshed the current frame, but no seeking was done. */ - void frameUpdated(int); + void frameUpdated(QImage); public slots: diff --git a/src/rgbparade.cpp b/src/rgbparade.cpp index 3e412ab7..3fe44412 100644 --- a/src/rgbparade.cpp +++ b/src/rgbparade.cpp @@ -37,11 +37,11 @@ QRect RGBParade::scopeRect() } QImage RGBParade::renderHUD(uint) { return QImage(); } -QImage RGBParade::renderScope(uint accelerationFactor) +QImage RGBParade::renderScope(uint accelerationFactor, QImage qimage) { QTime start = QTime::currentTime(); start.start(); - QImage parade = m_rgbParadeGenerator->calculateRGBParade(m_scopeRect.size(), m_activeRender->extractFrame(m_activeRender->seekFramePosition()), + QImage parade = m_rgbParadeGenerator->calculateRGBParade(m_scopeRect.size(), qimage, true, accelerationFactor); emit signalScopeRenderingFinished(start.elapsed(), accelerationFactor); return parade; diff --git a/src/rgbparade.h b/src/rgbparade.h index a02fb8da..21233cfe 100644 --- a/src/rgbparade.h +++ b/src/rgbparade.h @@ -39,7 +39,7 @@ private: bool isBackgroundDependingOnInput() const; QImage renderHUD(uint accelerationFactor); - QImage renderScope(uint accelerationFactor); + QImage renderScope(uint accelerationFactor, QImage); QImage renderBackground(uint accelerationFactor); }; diff --git a/src/vectorscope.cpp b/src/vectorscope.cpp index cca16ef1..01a41d4d 100644 --- a/src/vectorscope.cpp +++ b/src/vectorscope.cpp @@ -192,7 +192,7 @@ QImage Vectorscope::renderHUD(uint) return hud; } -QImage Vectorscope::renderScope(uint accelerationFactor) +QImage Vectorscope::renderScope(uint accelerationFactor, QImage qimage) { QTime start = QTime::currentTime(); QImage scope; @@ -202,7 +202,7 @@ QImage Vectorscope::renderScope(uint accelerationFactor) } else { scope = m_vectorscopeGenerator->calculateVectorscope(m_scopeRect.size(), - m_activeRender->extractFrame(m_activeRender->seekFramePosition()), + qimage, m_gain, (VectorscopeGenerator::PaintMode) ui->paintMode->itemData(ui->paintMode->currentIndex()).toInt(), m_aAxisEnabled->isChecked(), accelerationFactor); diff --git a/src/vectorscope.h b/src/vectorscope.h index 438efa4c..bf6e5c08 100644 --- a/src/vectorscope.h +++ b/src/vectorscope.h @@ -41,7 +41,7 @@ protected: ///// Implemented methods ///// QRect scopeRect(); QImage renderHUD(uint accelerationFactor); - QImage renderScope(uint accelerationFactor); + QImage renderScope(uint accelerationFactor, QImage); QImage renderBackground(uint accelerationFactor); bool isHUDDependingOnInput() const; bool isScopeDependingOnInput() const; diff --git a/src/waveform.cpp b/src/waveform.cpp index fdd22b97..c4191fa9 100644 --- a/src/waveform.cpp +++ b/src/waveform.cpp @@ -58,13 +58,13 @@ QImage Waveform::renderHUD(uint) return QImage(); } -QImage Waveform::renderScope(uint accelFactor) +QImage Waveform::renderScope(uint accelFactor, QImage qimage) { QTime start = QTime::currentTime(); start.start(); QImage wave = m_waveformGenerator->calculateWaveform(scopeRect().size(), - m_activeRender->extractFrame(m_activeRender->seekFramePosition()), true, accelFactor); + qimage, true, accelFactor); emit signalScopeRenderingFinished(start.elapsed(), 1); return wave; diff --git a/src/waveform.h b/src/waveform.h index 7e4f0739..d1e3735f 100644 --- a/src/waveform.h +++ b/src/waveform.h @@ -39,7 +39,7 @@ private: /// Implemented methods /// QRect scopeRect(); QImage renderHUD(uint); - QImage renderScope(uint); + QImage renderScope(uint, QImage); QImage renderBackground(uint); bool isHUDDependingOnInput() const; bool isScopeDependingOnInput() const; -- 2.39.2