From f555964fc8fd3452f2aa6d8217d20e2aa4013334 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Sat, 1 Sep 2012 18:03:45 +0200 Subject: [PATCH] Improve seeking (Don't ask MLT to seek while it is already seeking) --- src/customruler.cpp | 14 +++++++++--- src/customtrackview.cpp | 47 +++++++++++++++++++++++++-------------- src/customtrackview.h | 5 +++++ src/geometrywidget.cpp | 12 +++++++--- src/geometrywidget.h | 2 ++ src/keyframehelper.cpp | 25 ++++++++++++++------- src/keyframehelper.h | 3 ++- src/mainwindow.cpp | 7 +++--- src/monitor.cpp | 26 ++++++++++++++-------- src/projectlist.cpp | 4 ++++ src/renderer.cpp | 48 +++++++++++++++++++++------------------- src/renderer.h | 1 + src/smallruler.cpp | 49 ++++++++++++++++++++++++++++++++--------- src/smallruler.h | 6 +++-- src/trackview.cpp | 2 ++ 15 files changed, 171 insertions(+), 80 deletions(-) diff --git a/src/customruler.cpp b/src/customruler.cpp index 029f52c2..d1265173 100644 --- a/src/customruler.cpp +++ b/src/customruler.cpp @@ -44,6 +44,8 @@ static int littleMarkDistance; static int mediumMarkDistance; static int bigMarkDistance; +#define SEEK_INACTIVE (-1) + #include "definitions.h" const int CustomRuler::comboScale[] = { 1, 2, 5, 10, 25, 50, 125, 250, 500, 750, 1500, 3000, 6000, 12000}; @@ -123,7 +125,7 @@ void CustomRuler::slotDeleteGuide() void CustomRuler::slotGoToGuide(QAction *act) { - m_view->setCursorPos(act->data().toInt(), true); + m_view->seekCursorPos(act->data().toInt()); m_view->initCursorPos(act->data().toInt()); } @@ -166,7 +168,7 @@ void CustomRuler::mousePressEvent(QMouseEvent * event) m_view->updateSnapPoints(NULL); } if (m_moveCursor == RULER_CURSOR) { - m_view->setCursorPos((int) pos / m_factor); + m_view->seekCursorPos((int) pos / m_factor); m_clickPoint = event->pos(); m_startRate = m_rate; } @@ -193,7 +195,7 @@ void CustomRuler::mouseMoveEvent(QMouseEvent * event) } else return; } if (m_mouseMove == HORIZONTAL_MOVE) { - m_view->setCursorPos(pos); + m_view->seekCursorPos(pos); m_view->slotCheckPositionScrolling(); } else { int verticalDiff = m_startRate - (diff.y()) / 7; @@ -427,6 +429,12 @@ void CustomRuler::paintEvent(QPaintEvent *e) } // draw pointer + int pos = m_view->seekPosition(); + if (pos != SEEK_INACTIVE) { + pos = pos * m_factor - m_offset; + p.fillRect(pos - 1, 0, 3, height(), palette().highlight()); + } + const int value = m_view->cursorPos() * m_factor - m_offset; QPolygon pa(3); pa.setPoints(3, value - 6, BIG_MARK_X, value + 6, BIG_MARK_X, value, MAX_HEIGHT - 1); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 4c752319..57e84b73 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -87,6 +87,7 @@ #include #endif + //#define DEBUG bool sortGuidesList(const Guide *g1 , const Guide *g2) @@ -390,10 +391,10 @@ void CustomTrackView::slotCheckPositionScrolling() if (mapFromScene(m_cursorPos, 0).x() < 3) { horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 2); QTimer::singleShot(200, this, SLOT(slotCheckPositionScrolling())); - setCursorPos(mapToScene(QPoint(-2, 0)).x()); + seekCursorPos(mapToScene(QPoint(-2, 0)).x()); } else if (viewport()->width() - 3 < mapFromScene(m_cursorPos + 1, 0).x()) { horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 2); - setCursorPos(mapToScene(QPoint(viewport()->width(), 0)).x() + 1); + seekCursorPos(mapToScene(QPoint(viewport()->width(), 0)).x() + 1); QTimer::singleShot(200, this, SLOT(slotCheckPositionScrolling())); } } @@ -706,7 +707,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) { QGraphicsView::mouseMoveEvent(event); m_moveOpMode = SEEK; - setCursorPos(mappedXPos); + seekCursorPos(mappedXPos); slotCheckPositionScrolling(); return; } else m_moveOpMode = NONE; @@ -938,7 +939,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) } m_operationMode = SPACER; } else { - setCursorPos((int)(mapToScene(event->x(), 0).x())); + seekCursorPos((int)(mapToScene(event->x(), 0).x())); } //QGraphicsView::mousePressEvent(event); event->ignore(); @@ -3336,14 +3337,26 @@ void CustomTrackView::deleteClip(const QString &clipId) } } +void CustomTrackView::seekCursorPos(int pos) +{ + m_document->renderer()->seek(pos); + emit updateRuler(); +} + +int CustomTrackView::seekPosition() const +{ + return m_document->renderer()->requestedSeekPosition; +} + + void CustomTrackView::setCursorPos(int pos, bool seek) { - if (pos == m_cursorPos) return; - emit cursorMoved((int)(m_cursorPos), (int)(pos)); - m_cursorPos = pos; - if (seek) m_document->renderer()->seek(m_cursorPos); + if (pos != m_cursorPos) { + emit cursorMoved((int)(m_cursorPos), (int)(pos)); + m_cursorPos = pos; + m_cursorLine->setPos(m_cursorPos, 0); + } else if (m_autoScroll) checkScrolling(); - m_cursorLine->setPos(m_cursorPos, 0); } void CustomTrackView::updateCursorPos() @@ -5121,7 +5134,7 @@ void CustomTrackView::slotSeekToPreviousSnap() { updateSnapPoints(NULL); GenTime res = m_scene->previousSnapPoint(GenTime(m_cursorPos, m_document->fps())); - setCursorPos((int) res.frames(m_document->fps())); + seekCursorPos((int) res.frames(m_document->fps())); checkScrolling(); } @@ -5129,7 +5142,7 @@ void CustomTrackView::slotSeekToNextSnap() { updateSnapPoints(NULL); GenTime res = m_scene->nextSnapPoint(GenTime(m_cursorPos, m_document->fps())); - setCursorPos((int) res.frames(m_document->fps())); + seekCursorPos((int) res.frames(m_document->fps())); checkScrolling(); } @@ -5137,7 +5150,7 @@ void CustomTrackView::clipStart() { AbstractClipItem *item = getMainActiveClip(); if (item != NULL) { - setCursorPos((int) item->startPos().frames(m_document->fps())); + seekCursorPos((int) item->startPos().frames(m_document->fps())); checkScrolling(); } } @@ -5146,7 +5159,7 @@ void CustomTrackView::clipEnd() { AbstractClipItem *item = getMainActiveClip(); if (item != NULL) { - setCursorPos((int) item->endPos().frames(m_document->fps()) - 1); + seekCursorPos((int) item->endPos().frames(m_document->fps()) - 1); checkScrolling(); } } @@ -5430,7 +5443,7 @@ bool CustomTrackView::findString(const QString &text) for (int i = 0; i < m_searchPoints.size(); ++i) { marker = m_searchPoints.at(i).comment(); if (marker.contains(text, Qt::CaseInsensitive)) { - setCursorPos(m_searchPoints.at(i).time().frames(m_document->fps()), true); + seekCursorPos(m_searchPoints.at(i).time().frames(m_document->fps())); int vert = verticalScrollBar()->value(); int hor = cursorPos(); ensureVisible(hor, vert + 10, 2, 2, 50, 0); @@ -5443,7 +5456,7 @@ bool CustomTrackView::findString(const QString &text) void CustomTrackView::selectFound(QString track, QString pos) { - setCursorPos(m_document->timecode().getFrameCount(pos), true); + seekCursorPos(m_document->timecode().getFrameCount(pos)); slotSelectTrack(track.toInt()); selectClip(true); int vert = verticalScrollBar()->value(); @@ -5457,7 +5470,7 @@ bool CustomTrackView::findNextString(const QString &text) for (int i = m_findIndex + 1; i < m_searchPoints.size(); ++i) { marker = m_searchPoints.at(i).comment(); if (marker.contains(text, Qt::CaseInsensitive)) { - setCursorPos(m_searchPoints.at(i).time().frames(m_document->fps()), true); + seekCursorPos(m_searchPoints.at(i).time().frames(m_document->fps())); int vert = verticalScrollBar()->value(); int hor = cursorPos(); ensureVisible(hor, vert + 10, 2, 2, 50, 0); @@ -6526,7 +6539,7 @@ void CustomTrackView::updateClipTypeActions(ClipItem *clip) void CustomTrackView::slotGoToMarker(QAction *action) { int pos = action->data().toInt(); - setCursorPos(pos, true); + seekCursorPos(pos); } void CustomTrackView::reloadTransitionLumas() diff --git a/src/customtrackview.h b/src/customtrackview.h index dafe942c..a37f76ee 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -202,8 +202,11 @@ public: bool hasAudio(int track) const; int getFrameWidth(); + /** @brief Returns last requested seeking pos (or SEEK_INACTIVE if no seek). */ + int seekPosition() const; public slots: + void seekCursorPos(int pos); void setCursorPos(int pos, bool seek = true); void moveCursorPos(int delta); void updateCursorPos(); @@ -512,6 +515,8 @@ signals: void showTrackEffects(int, TrackInfo); /** @brief Update the track effect button that shows if a track has effects or not.*/ void updateTrackEffectState(int); + /** @brief Cursor position changed, repaint ruler.*/ + void updateRuler(); }; #endif diff --git a/src/geometrywidget.cpp b/src/geometrywidget.cpp index df76b254..0dbd932c 100644 --- a/src/geometrywidget.cpp +++ b/src/geometrywidget.cpp @@ -88,7 +88,7 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos, m_ui.buttonSync->setChecked(KdenliveSettings::transitionfollowcursor()); m_ui.buttonSync->setIconSize(iconSize); - connect(m_timeline, SIGNAL(positionChanged(int)), this, SLOT(slotPositionChanged(int))); + connect(m_timeline, SIGNAL(requestSeek(int)), this, SLOT(slotRequestSeek(int))); connect(m_timeline, SIGNAL(keyframeMoved(int)), this, SLOT(slotKeyframeMoved(int))); connect(m_timeline, SIGNAL(addKeyframe(int)), this, SLOT(slotAddKeyframe(int))); connect(m_timeline, SIGNAL(removeKeyframe(int)), this, SLOT(slotDeleteKeyframe(int))); @@ -344,6 +344,12 @@ void GeometryWidget::slotSyncPosition(int relTimelinePos) } } +void GeometryWidget::slotRequestSeek(int pos) +{ + if (KdenliveSettings::transitionfollowcursor()) + emit seekToPos(m_clipPos + pos); +} + void GeometryWidget::slotPositionChanged(int pos, bool seek) { @@ -352,9 +358,9 @@ void GeometryWidget::slotPositionChanged(int pos, bool seek) else m_timePos->setValue(pos); - m_timeline->blockSignals(true); + //m_timeline->blockSignals(true); m_timeline->setValue(pos); - m_timeline->blockSignals(false); + //m_timeline->blockSignals(false); Mlt::GeometryItem item; Mlt::GeometryItem previousItem; diff --git a/src/geometrywidget.h b/src/geometrywidget.h index 582d4495..64cb02aa 100644 --- a/src/geometrywidget.h +++ b/src/geometrywidget.h @@ -109,6 +109,8 @@ private slots: * @param seek (optional, default = true) Whether to seek timleine & project monitor to pos * If pos = -1 (default) the value of m_timePos is used. */ void slotPositionChanged(int pos = -1, bool seek = true); + /** @brief Seeking requested from timeline. */ + void slotRequestSeek(int pos); /** @brief Updates settings after a keyframe was moved to @param pos. */ void slotKeyframeMoved(int pos); /** @brief Adds a keyframe. diff --git a/src/keyframehelper.cpp b/src/keyframehelper.cpp index a1c9af93..91d926ba 100644 --- a/src/keyframehelper.cpp +++ b/src/keyframehelper.cpp @@ -33,6 +33,8 @@ const int margin = 5; const int cursorWidth = 6; +#define SEEK_INACTIVE (-1) + KeyframeHelper::KeyframeHelper(QWidget *parent) : QWidget(parent), m_geom(NULL), @@ -41,7 +43,8 @@ KeyframeHelper::KeyframeHelper(QWidget *parent) : m_movingKeyframe(false), m_lineHeight(9), m_drag(false), - m_hoverKeyframe(-1) + m_hoverKeyframe(-1), + m_seekPosition(SEEK_INACTIVE) { setFont(KGlobalSettings::toolBarFont()); setMouseTracking(true); @@ -98,8 +101,8 @@ void KeyframeHelper::mousePressEvent(QMouseEvent * event) } if (event->y() >= m_lineHeight && event->y() < height()) { m_drag = true; - m_position = xPos / m_scale; - emit positionChanged(m_position); + m_seekPosition = xPos / m_scale; + emit requestSeek(m_seekPosition); update(); } } @@ -167,11 +170,11 @@ void KeyframeHelper::mouseMoveEvent(QMouseEvent * event) update(); return; } - m_position = xPos / m_scale; - m_position = qMax(0, m_position); - m_position = qMin(frameLength, m_position); + m_seekPosition = (int) (xPos / m_scale); + m_seekPosition = qMax(0, m_seekPosition); + m_seekPosition = qMin(frameLength, m_seekPosition); m_hoverKeyframe = -2; - emit positionChanged(m_position); + emit requestSeek(m_seekPosition); update(); } @@ -221,7 +224,7 @@ void KeyframeHelper::wheelEvent(QWheelEvent * e) ++m_position; m_position = qMax(0, m_position); m_position = qMin(frameLength, m_position); - emit positionChanged(m_position); + emit requestSeek(m_position); update(); /* int delta = 1; if (e->modifiers() == Qt::ControlModifier) delta = m_timecode.fps(); @@ -289,6 +292,9 @@ void KeyframeHelper::paintEvent(QPaintEvent *e) p.drawLine(width() - margin - 1, m_lineHeight - 3, width() - margin - 1, m_lineHeight + 3); // draw pointer + if (m_seekPosition != SEEK_INACTIVE) { + p.fillRect(margin + m_seekPosition * m_scale - 1, 0, 3, height(), palette().dark()); + } QPolygon pa(3); const int cursor = margin + m_position * m_scale; pa.setPoints(3, cursor - cursorWidth, 16, cursor + cursorWidth, 16, cursor, 10); @@ -307,6 +313,9 @@ int KeyframeHelper::value() const void KeyframeHelper::setValue(const int pos) { if (pos == m_position || m_geom == NULL) return; + if (pos == m_seekPosition) { + m_seekPosition = SEEK_INACTIVE; + } m_position = pos; update(); } diff --git a/src/keyframehelper.h b/src/keyframehelper.h index 4e8d7afe..a3d7b28d 100644 --- a/src/keyframehelper.h +++ b/src/keyframehelper.h @@ -59,6 +59,7 @@ private: QColor m_keyframe; QColor m_keyframebg; QList m_extraGeometries; + int m_seekPosition; public slots: void setKeyGeometry(Mlt::Geometry *geom, const int length); @@ -66,7 +67,7 @@ public slots: void setValue(const int pos); signals: - void positionChanged(int); + void requestSeek(int); void keyframeMoved(int); void addKeyframe(int); void removeKeyframe(int); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2712972c..ad1cf6e8 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -916,6 +916,8 @@ void MainWindow::slotConnectMonitors() connect(m_projectList, SIGNAL(showClipProperties(QList , QMap)), this, SLOT(slotShowClipProperties(QList , QMap))); connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QString &, int, int)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QString &, int, int))); connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QImage &)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QImage &))); + + kDebug()<<" - - - - - -\n CONNECTED REPLY"; connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const stringMap &, const stringMap &, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const stringMap &, const stringMap &, bool))); connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &, bool))); @@ -2555,7 +2557,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_projectList, SIGNAL(projectModified()), doc, SLOT(setModified())); connect(m_projectList, SIGNAL(clipNameChanged(const QString, const QString)), trackView->projectView(), SLOT(clipNameChanged(const QString, const QString))); - //connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor())); connect(trackView, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int))); connect(trackView, SIGNAL(updateTracksInfo()), this, SLOT(slotUpdateTrackInfo())); connect(trackView, SIGNAL(mousePosition(int)), this, SLOT(slotUpdateMousePosition(int))); @@ -2606,13 +2607,13 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, QList , bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, QList , bool))); connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList , int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList , int))); connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*))); - connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int))); + connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(seekCursorPos(int))); connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects())); connect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); // Transition config signals connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement))); - connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int))); + connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(seekCursorPos(int))); connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor())); connect(trackView, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int))); diff --git a/src/monitor.cpp b/src/monitor.cpp index 34eb1de5..ccba5b59 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -43,11 +43,13 @@ #include +#define SEEK_INACTIVE (-1) + + Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profile, QWidget *parent) : AbstractMonitor(id, manager, parent), render(NULL), m_currentClip(NULL), - m_ruler(new SmallRuler(m_monitorManager)), m_overlay(NULL), m_scale(1), m_length(0), @@ -69,8 +71,7 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil // Get base size for icons int s = style()->pixelMetric(QStyle::PM_SmallIconSize); - // Monitor ruler - layout->addWidget(m_ruler); + // Tool bar buttons m_toolbar = new QToolBar(this); m_toolbar->setIconSize(QSize(s, s)); @@ -78,11 +79,10 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil m_playIcon = KIcon("media-playback-start"); m_pauseIcon = KIcon("media-playback-pause"); + if (id != Kdenlive::dvdMonitor) { m_toolbar->addAction(KIcon("kdenlive-zone-start"), i18n("Set zone start"), this, SLOT(slotSetZoneStart())); m_toolbar->addAction(KIcon("kdenlive-zone-end"), i18n("Set zone end"), this, SLOT(slotSetZoneEnd())); - } else { - m_ruler->setZone(-3, -2); } m_toolbar->addAction(KIcon("media-seek-backward"), i18n("Rewind"), this, SLOT(slotRewind())); @@ -169,6 +169,11 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil } #endif + // Monitor ruler + m_ruler = new SmallRuler(m_monitorManager, render); + if (id == Kdenlive::dvdMonitor) m_ruler->setZone(-3, -2); + layout->addWidget(m_ruler); + connect(m_audioSlider, SIGNAL(valueChanged(int)), this, SLOT(slotSetVolume(int))); connect(m_ruler, SIGNAL(seekRenderer(int)), this, SLOT(slotSeek(int))); connect(render, SIGNAL(durationChanged(int)), this, SLOT(adjustRulerSize(int))); @@ -419,7 +424,7 @@ void Monitor::slotZoneMoved(int start, int end) void Monitor::slotSetZoneStart() { - m_ruler->setZone(m_ruler->position(), -1); + m_ruler->setZoneStart(); emit zoneUpdated(m_ruler->zone()); checkOverlay(); setClipZone(m_ruler->zone()); @@ -427,7 +432,7 @@ void Monitor::slotSetZoneStart() void Monitor::slotSetZoneEnd() { - m_ruler->setZone(-1, m_ruler->position()); + m_ruler->setZoneEnd(); emit zoneUpdated(m_ruler->zone()); checkOverlay(); setClipZone(m_ruler->zone()); @@ -546,7 +551,7 @@ void Monitor::slotMouseSeek(int eventDelta, bool fast) if (fast) { int delta = m_monitorManager->timecode().fps(); if (eventDelta > 0) delta = 0 - delta; - slotSeek(m_ruler->position() - delta); + slotSeek(render->requestedSeekPosition - delta); } else { if (eventDelta >= 0) slotForwardOneFrame(); else slotRewindOneFrame(); @@ -607,13 +612,14 @@ void Monitor::slotSeek(int pos) if (render == NULL) return; slotActivateMonitor(); render->seekToFrame(pos); + m_ruler->update(); } void Monitor::checkOverlay() { if (m_overlay == NULL) return; QString overlayText; - int pos = m_ruler->position(); + int pos = render->seekFramePosition(); QPoint zone = m_ruler->zone(); if (pos == zone.x()) overlayText = i18n("In Point"); @@ -689,6 +695,7 @@ void Monitor::slotRewindOneFrame(int diff) slotActivateMonitor(); render->play(0); render->seekToFrameDiff(-diff); + m_ruler->update(); } void Monitor::slotForwardOneFrame(int diff) @@ -696,6 +703,7 @@ void Monitor::slotForwardOneFrame(int diff) slotActivateMonitor(); render->play(0); render->seekToFrameDiff(diff); + m_ruler->update(); } void Monitor::seekCursor(int pos) diff --git a/src/projectlist.cpp b/src/projectlist.cpp index df1ac4f5..9e5c1e53 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -1278,6 +1278,7 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) //m_listView->setEnabled(false); const QString parent = clip->getProperty("groupid"); ProjectItem *item = NULL; + kDebug()<<"// Adding clip 1"; monitorItemEditing(false); if (!parent.isEmpty()) { FolderProjectItem *parentitem = getFolderItemById(parent); @@ -1296,6 +1297,7 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) if (item == NULL) { item = new ProjectItem(m_listView, clip); } + kDebug()<<"// Adding clip 2"; if (item->data(0, DurationRole).isNull()) item->setData(0, DurationRole, i18n("Loading")); connect(clip, SIGNAL(createProxy(const QString &)), this, SLOT(slotCreateProxy(const QString &))); connect(clip, SIGNAL(abortProxy(const QString &, const QString &)), this, SLOT(slotAbortProxy(const QString, const QString))); @@ -2110,6 +2112,7 @@ void ProjectList::slotRefreshClipThumbnail(QTreeWidgetItem *it, bool update) void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Producer *producer, const stringMap &properties, const stringMap &metadata, bool replace) { QString toReload; + kDebug()<<"// CLIP LOADED 1;"; ProjectItem *item = getItemById(clipId); int queue = m_render->processingItems(); if (item && producer) { @@ -2167,6 +2170,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce if (queue == 0) { monitorItemEditing(true); if (item && m_thumbnailQueue.isEmpty()) { + kDebug()<<"// CLIP LOADED;"; if (!item->hasProxy() || m_render->activeClipId() == item->clipId()) m_listView->setCurrentItem(item); bool updatedProfile = false; diff --git a/src/renderer.cpp b/src/renderer.cpp index 5effeb81..d675671f 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -53,6 +53,7 @@ #include +#define SEEK_INACTIVE (-1) static void kdenlive_callback(void* /*ptr*/, int level, const char* fmt, va_list vl) { @@ -105,6 +106,7 @@ static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ Render::Render(Kdenlive::MONITORID rendererName, int winid, QString profile, QWidget *parent) : AbstractRender(rendererName, parent), + requestedSeekPosition(SEEK_INACTIVE), m_name(rendererName), m_mltConsumer(NULL), m_mltProducer(NULL), @@ -376,24 +378,21 @@ int Render::resetProfile(const QString &profileName, bool dropSceneList) void Render::seek(GenTime time) { - if (!m_mltProducer) - return; - - m_mltProducer->seek((int)(time.frames(m_fps))); - if (m_mltProducer->get_speed() == 0) { - refresh(); - } + int pos = time.frames(m_fps); + seek(pos); } void Render::seek(int time) { if (!m_mltProducer) return; - - m_mltProducer->seek(time); - if (m_mltProducer->get_speed() == 0) { - refresh(); + if (requestedSeekPosition == SEEK_INACTIVE) { + m_mltProducer->seek(time); + if (m_mltProducer->get_speed() == 0) { + refresh(); + } } + requestedSeekPosition = time; } //static @@ -1032,6 +1031,7 @@ void Render::initSceneList() int Render::setProducer(Mlt::Producer *producer, int position) { m_refreshTimer.stop(); + requestedSeekPosition = SEEK_INACTIVE; QMutexLocker locker(&m_mutex); QString currentId; int consumerPosition = 0; @@ -1106,6 +1106,7 @@ int Render::setSceneList(QDomDocument list, int position) int Render::setSceneList(QString playlist, int position) { + requestedSeekPosition = SEEK_INACTIVE; m_refreshTimer.stop(); QMutexLocker locker(&m_mutex); if (m_winid == -1) return -1; @@ -1452,6 +1453,7 @@ void Render::pause() void Render::switchPlay(bool play) { QMutexLocker locker(&m_mutex); + requestedSeekPosition = SEEK_INACTIVE; if (!m_mltProducer || !m_mltConsumer) return; if (m_isZoneMode) resetZoneMode(); @@ -1527,7 +1529,7 @@ void Render::playZone(const GenTime & startTime, const GenTime & stopTime) void Render::resetZoneMode() { - if (!m_isZoneMode && !m_isLoopMode) return; + if (!m_mltProducer || (!m_isZoneMode && !m_isLoopMode)) return; m_mltProducer->set("out", m_originalOut); //m_mltProducer->set("eof", "pause"); m_isZoneMode = false; @@ -1536,22 +1538,14 @@ void Render::resetZoneMode() void Render::seekToFrame(int pos) { - if (!m_mltProducer) - return; resetZoneMode(); - m_mltProducer->seek(pos); - if (m_mltProducer->get_speed() == 0) { - refresh(); - } + seek(pos); } void Render::seekToFrameDiff(int diff) { - if (!m_mltProducer) - return; resetZoneMode(); - m_mltProducer->seek(m_mltProducer->position() + diff); - refresh(); + seek(m_mltProducer->position() + diff); } void Render::doRefresh() @@ -1629,7 +1623,15 @@ void Render::emitFrameUpdated(Mlt::Frame& frame) void Render::emitFrameNumber() { - if (m_mltConsumer) emit rendererPosition((int) m_mltConsumer->position()); + int currentPos = m_mltConsumer->position(); + if (currentPos == requestedSeekPosition) requestedSeekPosition = SEEK_INACTIVE; + emit rendererPosition(currentPos); + if (requestedSeekPosition != SEEK_INACTIVE) { + m_mltProducer->seek(requestedSeekPosition); + if (m_mltProducer->get_speed() == 0) { + refresh(); + } + } } void Render::emitConsumerStopped() diff --git a/src/renderer.h b/src/renderer.h index 637ba0c9..2c81c830 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -320,6 +320,7 @@ Q_OBJECT public: static bool getBlackMagicOutputDeviceList(KComboBox *devicelist); /** @brief Frame rendering is handeled by Kdenlive, don't show video through SDL display */ void disablePreview(bool disable); + int requestedSeekPosition; private: diff --git a/src/smallruler.cpp b/src/smallruler.cpp index 89d876d8..a00d388b 100644 --- a/src/smallruler.cpp +++ b/src/smallruler.cpp @@ -28,13 +28,16 @@ #include #include +#define SEEK_INACTIVE (-1) -SmallRuler::SmallRuler(MonitorManager *manager, QWidget *parent) : + +SmallRuler::SmallRuler(MonitorManager *manager, Render *render, QWidget *parent) : QWidget(parent) ,m_cursorFramePosition(0) ,m_scale(1) ,m_maxval(25) ,m_manager(manager) + ,m_render(render) ,m_overCursor(false) { m_zoneStart = 10; @@ -46,6 +49,7 @@ SmallRuler::SmallRuler(MonitorManager *manager, QWidget *parent) : setMinimumHeight(10); } + void SmallRuler::adjustScale(int maximum) { m_maxval = maximum; @@ -62,10 +66,23 @@ void SmallRuler::adjustScale(int maximum) m_small = 30 * 25; m_medium = 60 * 25; } - m_cursorPosition = m_cursorFramePosition * m_scale; updatePixmap(); } +void SmallRuler::setZoneStart() +{ + int pos = m_render->requestedSeekPosition; + if (pos == SEEK_INACTIVE) pos = m_render->seekFramePosition(); + m_zoneStart = pos; +} + +void SmallRuler::setZoneEnd() +{ + int pos = m_render->requestedSeekPosition; + if (pos == SEEK_INACTIVE) pos = m_render->seekFramePosition(); + m_zoneEnd = pos; +} + void SmallRuler::setZone(int start, int end) { if (start != -1) { @@ -111,7 +128,9 @@ void SmallRuler::mousePressEvent(QMouseEvent * event) emit zoneChanged(QPoint(m_zoneStart, m_zoneEnd)); updatePixmap(); - } else emit seekRenderer((int) pos); + } else { + emit seekRenderer((int) pos); + } } void SmallRuler::leaveEvent( QEvent * event ) @@ -128,7 +147,7 @@ void SmallRuler::mouseMoveEvent(QMouseEvent * event) { const int pos = event->x() / m_scale; if (event->button() == Qt::NoButton) { - if (qAbs(pos * m_scale - m_cursorPosition) < 6) { + if (qAbs(pos * m_scale - m_render->seekFramePosition()) < 6) { if (!m_overCursor) { m_overCursor = true; update(); @@ -142,6 +161,7 @@ void SmallRuler::mouseMoveEvent(QMouseEvent * event) if (event->buttons() & Qt::LeftButton) { m_overCursor = true; emit seekRenderer((int) pos); + update(); } else { if (qAbs((pos - m_zoneStart) * m_scale) < 4) { @@ -156,21 +176,18 @@ void SmallRuler::mouseMoveEvent(QMouseEvent * event) bool SmallRuler::slotNewValue(int value) { - if (value == m_cursorFramePosition) return false; + /*if (value == m_cursorFramePosition) return false; m_cursorFramePosition = value; int oldPos = m_cursorPosition; m_cursorPosition = value * m_scale; const int offset = 6; const int x = qMin(oldPos, m_cursorPosition); const int w = qAbs(oldPos - m_cursorPosition); - update(x - offset, 4, w + 2 * offset, 6); + update(x - offset, 0, w + 2 * offset, height());*/ + update(); return true; } -int SmallRuler::position() const -{ - return m_cursorFramePosition; -} //virtual void SmallRuler::resizeEvent(QResizeEvent *) @@ -224,9 +241,19 @@ void SmallRuler::paintEvent(QPaintEvent *e) p.setClipRect(r); p.drawPixmap(QPointF(), m_pixmap); + int seekPos; + int cursorPos = m_render->seekFramePosition() * m_scale; + if (m_render->requestedSeekPosition != SEEK_INACTIVE) { + seekPos = m_render->requestedSeekPosition * m_scale - 1; + } + else seekPos = cursorPos - 1; + + // Draw seeking pointer + p.fillRect(seekPos, 0, 3, height(), palette().text()); + // draw pointer QPolygon pa(3); - pa.setPoints(3, m_cursorPosition - 6, 10, m_cursorPosition + 6, 10, m_cursorPosition/*+0*/, 4); + pa.setPoints(3, cursorPos - 6, 10, cursorPos + 6, 10, cursorPos/*+0*/, 4); if (m_overCursor) p.setBrush(palette().highlight()); else p.setBrush(palette().text().color()); p.setPen(Qt::NoPen); diff --git a/src/smallruler.h b/src/smallruler.h index f3ccc725..bbf033a6 100644 --- a/src/smallruler.h +++ b/src/smallruler.h @@ -32,15 +32,16 @@ class SmallRuler : public QWidget Q_OBJECT public: - explicit SmallRuler(MonitorManager *manager, QWidget *parent = 0); + explicit SmallRuler(MonitorManager *manager, Render *render, QWidget *parent = 0); virtual void mousePressEvent(QMouseEvent * event); virtual void mouseMoveEvent(QMouseEvent * event); virtual void leaveEvent( QEvent * event ); void adjustScale(int maximum); void setZone(int start, int end); + void setZoneStart(); + void setZoneEnd(); QPoint zone(); void setMarkers(QList < int > list); - int position() const; void updatePalette(); protected: @@ -60,6 +61,7 @@ private: QList m_markers; QPixmap m_pixmap; MonitorManager *m_manager; + Render *m_render; /** @brief True is mouse is over the ruler cursor. */ bool m_overCursor; void updatePixmap(); diff --git a/src/trackview.cpp b/src/trackview.cpp index af723ce5..2f190746 100644 --- a/src/trackview.cpp +++ b/src/trackview.cpp @@ -113,6 +113,8 @@ TrackView::TrackView(KdenliveDoc *doc, QList actions, bool *ok, QWidg if (m_doc->setSceneList() == -1) *ok = false; else *ok = true; connect(m_trackview, SIGNAL(cursorMoved(int, int)), m_ruler, SLOT(slotCursorMoved(int, int))); + connect(m_trackview, SIGNAL(updateRuler()), m_ruler, SLOT(update())); + connect(m_trackview->horizontalScrollBar(), SIGNAL(valueChanged(int)), m_ruler, SLOT(slotMoveRuler(int))); connect(m_trackview->horizontalScrollBar(), SIGNAL(rangeChanged(int, int)), this, SLOT(slotUpdateVerticalScroll(int, int))); connect(m_trackview, SIGNAL(mousePosition(int)), this, SIGNAL(mousePosition(int))); -- 2.39.2