From 485eee3beffea9b2504b84925ec096e82bbe1ea0 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Mon, 29 Oct 2012 12:35:31 +0100 Subject: [PATCH] Do not switch monitor when not necessary, make sure we refresh monitor when adding / deleting timeline clip --- src/abstractmonitor.cpp | 4 +-- src/abstractmonitor.h | 2 +- src/commands/CMakeLists.txt | 1 + src/commands/refreshmonitorcommand.cpp | 46 ++++++++++++++++++++++++++ src/commands/refreshmonitorcommand.h | 41 +++++++++++++++++++++++ src/customtrackview.cpp | 13 +++++++- src/customtrackview.h | 3 ++ src/mainwindow.cpp | 2 +- src/monitor.cpp | 3 +- src/monitormanager.cpp | 6 ++-- src/monitormanager.h | 2 +- src/projectlist.cpp | 2 +- src/projectlist.h | 2 +- src/projectlistview.cpp | 2 +- src/projectlistview.h | 2 +- src/renderer.cpp | 22 ++++++++---- src/renderer.h | 4 +++ 17 files changed, 137 insertions(+), 20 deletions(-) create mode 100644 src/commands/refreshmonitorcommand.cpp create mode 100644 src/commands/refreshmonitorcommand.h diff --git a/src/abstractmonitor.cpp b/src/abstractmonitor.cpp index fa6f43c9..e66a4bd1 100644 --- a/src/abstractmonitor.cpp +++ b/src/abstractmonitor.cpp @@ -59,9 +59,9 @@ bool AbstractMonitor::isActive() const return m_monitorManager->isActive(m_id); } -bool AbstractMonitor::slotActivateMonitor() +bool AbstractMonitor::slotActivateMonitor(bool forceRefresh) { - return m_monitorManager->activateMonitor(m_id); + return m_monitorManager->activateMonitor(m_id, forceRefresh); } VideoContainer::VideoContainer(AbstractMonitor* monitor, QWidget *parent) : diff --git a/src/abstractmonitor.h b/src/abstractmonitor.h index 0a821288..eec0cfef 100644 --- a/src/abstractmonitor.h +++ b/src/abstractmonitor.h @@ -105,7 +105,7 @@ public slots: virtual void start() = 0; virtual void slotPlay() = 0; virtual void slotMouseSeek(int eventDelta, bool fast) = 0; - bool slotActivateMonitor(); + bool slotActivateMonitor(bool forceRefresh = false); virtual void slotSwitchFullScreen() = 0; protected: diff --git a/src/commands/CMakeLists.txt b/src/commands/CMakeLists.txt index 5da8b75b..cface28b 100644 --- a/src/commands/CMakeLists.txt +++ b/src/commands/CMakeLists.txt @@ -30,6 +30,7 @@ set(kdenlive_SRCS commands/razorclipcommand.cpp commands/razorgroupcommand.cpp commands/rebuildgroupcommand.cpp + commands/refreshmonitorcommand.cpp commands/resizeclipcommand.cpp commands/splitaudiocommand.cpp PARENT_SCOPE diff --git a/src/commands/refreshmonitorcommand.cpp b/src/commands/refreshmonitorcommand.cpp new file mode 100644 index 00000000..8130bbb3 --- /dev/null +++ b/src/commands/refreshmonitorcommand.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2012 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#include "refreshmonitorcommand.h" +#include "customtrackview.h" + + +RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, bool execute, QUndoCommand * parent) : + QUndoCommand(parent), + m_view(view), + m_exec(execute) +{ +} + + +// virtual +void RefreshMonitorCommand::undo() +{ + m_view->monitorRefresh(); +} +// virtual +void RefreshMonitorCommand::redo() +{ + if (m_exec) + m_view->monitorRefresh(); + m_exec = true; +} + + diff --git a/src/commands/refreshmonitorcommand.h b/src/commands/refreshmonitorcommand.h new file mode 100644 index 00000000..5a11a4ce --- /dev/null +++ b/src/commands/refreshmonitorcommand.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2012 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef REFRESHMONITORCOMMAND_H +#define REFRESHMONITORCOMMAND_H + +#include + +class CustomTrackView; + +class RefreshMonitorCommand : public QUndoCommand +{ +public: + RefreshMonitorCommand(CustomTrackView *view, bool execute, QUndoCommand * parent = 0); + virtual void undo(); + virtual void redo(); + +private: + CustomTrackView *m_view; + bool m_exec; +}; + +#endif + diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index addd479f..84952f9b 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -63,6 +63,7 @@ #include "commands/configtrackscommand.h" #include "commands/rebuildgroupcommand.h" #include "commands/razorgroupcommand.h" +#include "commands/refreshmonitorcommand.h" #include "profilesdialog.h" #include "lib/audio/audioEnvelope.h" @@ -2711,7 +2712,7 @@ void CustomTrackView::dropEvent(QDropEvent * event) m_dragItem = static_cast (items.at(0)); emit clipItemSelected((ClipItem*) m_dragItem, false); } - m_document->renderer()->doRefresh(); + m_document->renderer()->refreshIfActive(); event->setDropAction(Qt::MoveAction); event->accept(); @@ -3428,8 +3429,10 @@ void CustomTrackView::deleteClip(const QString &clipId) delete deleteCommand; } else { updateTrackDuration(-1, deleteCommand); + new RefreshMonitorCommand(this, false, deleteCommand); m_commandStack->push(deleteCommand); } + m_document->renderer()->doRefresh(); } void CustomTrackView::seekCursorPos(int pos) @@ -4197,7 +4200,9 @@ void CustomTrackView::deleteSelectedClips() deleteSelected->setText(i18np("Delete selected transition", "Delete selected transitions", transitionCount)); else deleteSelected->setText(i18n("Delete selected items")); updateTrackDuration(-1, deleteSelected); + new RefreshMonitorCommand(this, false, deleteSelected); m_commandStack->push(deleteSelected); + m_document->renderer()->doRefresh(); } @@ -6011,6 +6016,7 @@ void CustomTrackView::pasteClip() } } updateTrackDuration(-1, pasteClips); + new RefreshMonitorCommand(this, false, pasteClips); m_commandStack->push(pasteClips); } @@ -6823,6 +6829,11 @@ void CustomTrackView::setAudioAndVideo() m_commandStack->push(videoCommand); } +void CustomTrackView::monitorRefresh() +{ + m_document->renderer()->doRefresh(); +} + void CustomTrackView::doChangeClipType(const GenTime &pos, int track, bool videoOnly, bool audioOnly) { ClipItem *clip = getClipItemAt(pos, track); diff --git a/src/customtrackview.h b/src/customtrackview.h index 5515c7e8..f27f9710 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -205,6 +205,9 @@ public: int getFrameWidth(); /** @brief Returns last requested seeking pos (or SEEK_INACTIVE if no seek). */ int seekPosition() const; + + /** @brief Trigger a monitor refresh. */ + void monitorRefresh(); public slots: /** @brief Send seek request to MLT. */ diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index da448cc9..9139b6d2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -234,7 +234,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & // Connect the project list connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint, bool)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool))); - connect(m_projectList, SIGNAL(raiseClipMonitor()), m_clipMonitor, SLOT(slotActivateMonitor())); + connect(m_projectList, SIGNAL(raiseClipMonitor(bool)), m_clipMonitor, SLOT(slotActivateMonitor(bool))); connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime())); connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus())); diff --git a/src/monitor.cpp b/src/monitor.cpp index 67b35e92..02a9d921 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -743,7 +743,7 @@ void Monitor::stop() void Monitor::start() { if (!isVisible() || !isActive()) return; - if (render) render->doRefresh();// start(); + if (render) render->startConsumer(); } void Monitor::refreshMonitor(bool visible) @@ -842,7 +842,6 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda if (m_currentClip) m_currentClip->lastSeekPosition = render->seekFramePosition(); m_currentClip = clip; if (position == -1) position = clip->lastSeekPosition; - if (m_currentClip) slotActivateMonitor(); updateMarkers(clip); Mlt::Producer *prod = NULL; if (clip) prod = clip->getCloneProducer(); diff --git a/src/monitormanager.cpp b/src/monitormanager.cpp index 09c6c1e1..178ffc1d 100644 --- a/src/monitormanager.cpp +++ b/src/monitormanager.cpp @@ -74,12 +74,14 @@ AbstractMonitor* MonitorManager::monitor(Kdenlive::MONITORID monitorName) return monitor; } -bool MonitorManager::activateMonitor(Kdenlive::MONITORID name) +bool MonitorManager::activateMonitor(Kdenlive::MONITORID name, bool forceRefresh) { if (m_clipMonitor == NULL || m_projectMonitor == NULL) return false; - if (m_activeMonitor && m_activeMonitor->id() == name) + if (m_activeMonitor && m_activeMonitor->id() == name) { + if (forceRefresh) m_activeMonitor->start(); return false; + } m_activeMonitor = NULL; for (int i = 0; i < m_monitorsList.count(); i++) { if (m_monitorsList.at(i)->id() == name) { diff --git a/src/monitormanager.h b/src/monitormanager.h index 880b6d12..8ce0e3f3 100644 --- a/src/monitormanager.h +++ b/src/monitormanager.h @@ -50,7 +50,7 @@ public slots: /** @brief Activates a monitor. * @param name name of the monitor to activate */ - bool activateMonitor(Kdenlive::MONITORID); + bool activateMonitor(Kdenlive::MONITORID, bool forceRefresh = false); bool isActive(Kdenlive::MONITORID id) const; void slotPlay(); void slotPause(); diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 022b1971..3cb9cad7 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -310,7 +310,7 @@ ProjectList::ProjectList(QWidget *parent) : connect(this, SIGNAL(processNextThumbnail()), this, SLOT(slotProcessNextThumbnail())); connect(m_listView, SIGNAL(projectModified()), this, SIGNAL(projectModified())); connect(m_listView, SIGNAL(itemSelectionChanged()), this, SLOT(slotClipSelected())); - connect(m_listView, SIGNAL(focusMonitor()), this, SIGNAL(raiseClipMonitor())); + connect(m_listView, SIGNAL(focusMonitor(bool)), this, SIGNAL(raiseClipMonitor(bool))); connect(m_listView, SIGNAL(pauseMonitor()), this, SIGNAL(pauseMonitor())); connect(m_listView, SIGNAL(requestMenu(const QPoint &, QTreeWidgetItem *)), this, SLOT(slotContextMenu(const QPoint &, QTreeWidgetItem *))); connect(m_listView, SIGNAL(addClip()), this, SIGNAL(pauseMonitor())); diff --git a/src/projectlist.h b/src/projectlist.h index ef290dad..49bccdf0 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -515,7 +515,7 @@ signals: void updateProfile(const QString &); void processNextThumbnail(); /** @brief Activate the clip monitor. */ - void raiseClipMonitor(); + void raiseClipMonitor(bool forceRefresh); /** @brief Set number of running jobs. */ void jobCount(int); void cancelRunningJob(const QString, stringMap); diff --git a/src/projectlistview.cpp b/src/projectlistview.cpp index 21e212c2..74f306bf 100644 --- a/src/projectlistview.cpp +++ b/src/projectlistview.cpp @@ -333,7 +333,7 @@ void ProjectListView::mouseReleaseEvent(QMouseEvent *event) { QTreeWidget::mouseReleaseEvent(event); QTreeWidgetItem *underMouse = itemAt(event->pos()); - if (underMouse) emit focusMonitor(); + if (underMouse) emit focusMonitor(true); } // virtual diff --git a/src/projectlistview.h b/src/projectlistview.h index 26e2c581..55a0e212 100644 --- a/src/projectlistview.h +++ b/src/projectlistview.h @@ -70,7 +70,7 @@ signals: void addClip(); void addClip(const QList , const QString &, const QString &); void showProperties(DocClipBase *); - void focusMonitor(); + void focusMonitor(bool forceRefresh); void pauseMonitor(); void addClipCut(const QString&, int, int); void projectModified(); diff --git a/src/renderer.cpp b/src/renderer.cpp index 12e30d94..d54c90e6 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1095,8 +1095,10 @@ int Render::setProducer(Mlt::Producer *producer, int position) if (producer) delete producer; return -1; } + bool monitorIsActive = false; m_mltConsumer->set("refresh", 0); if (!m_mltConsumer->is_stopped()) { + monitorIsActive = true; m_mltConsumer->stop(); } m_mltConsumer->purge(); @@ -1160,8 +1162,15 @@ int Render::setProducer(Mlt::Producer *producer, int position) } m_mltProducer = producer; m_mltProducer->set_speed(0); + if (monitorIsActive) startConsumer(); emit durationChanged(m_mltProducer->get_playtime()); - if (m_mltConsumer->start() == -1) { + position = m_mltProducer->position(); + emit rendererPosition(position); + return 0; +} + +void Render::startConsumer() { + if (m_mltConsumer->is_stopped() && m_mltConsumer->start() == -1) { // ARGH CONSUMER BROKEN!!!! 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; @@ -1170,18 +1179,14 @@ int Render::setProducer(Mlt::Producer *producer, int position) m_pauseEvent = NULL; delete m_mltConsumer; m_mltConsumer = NULL; - return -1; + return; } - - position = m_mltProducer->position(); m_mltConsumer->set("refresh", 1); // Make sure the first frame is displayed, otherwise if we change producer too fast // We can crash the avformat producer Mlt::Event *ev = m_mltConsumer->setup_wait_for("consumer-frame-show"); m_mltConsumer->wait_for(ev); delete ev; - emit rendererPosition(position); - return 0; } int Render::setSceneList(QDomDocument list, int position) @@ -1641,6 +1646,11 @@ void Render::seekToFrameDiff(int diff) else seek(requestedSeekPosition + diff); } +void Render::refreshIfActive() +{ + if (!m_mltConsumer->is_stopped() && m_mltProducer && m_mltProducer->get_speed() == 0) m_refreshTimer.start(); +} + void Render::doRefresh() { if (m_mltProducer && m_mltProducer->get_speed() == 0) m_refreshTimer.start(); diff --git a/src/renderer.h b/src/renderer.h index f1ca980c..9813d627 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -199,6 +199,10 @@ Q_OBJECT public: double dar() const; /** @brief Returns sample aspect ratio. */ double sar() const; + /** @brief If monitor is active, refresh it. */ + void refreshIfActive(); + /** @brief Start the MLT monitor consumer. */ + void startConsumer(); /* * Playlist manipulation. -- 2.39.2