monitor.h 15.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/***************************************************************************
 *   Copyright (C) 2007 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          *
 ***************************************************************************/

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
20
21
22
#ifndef MONITOR_H
#define MONITOR_H

Vincent Pinon's avatar
Vincent Pinon committed
23
#include "abstractmonitor.h"
Nicolas Carion's avatar
linting    
Nicolas Carion committed
24
#include "bin/model/markerlistmodel.hpp"
Nicolas Carion's avatar
Nicolas Carion committed
25
#include "definitions.h"
26
#include "gentime.h"
27
#include "scopes/sharedframe.h"
Nicolas Carion's avatar
Nicolas Carion committed
28
#include "timecodedisplay.h"
29

30
#include <QTimer>
Nicolas Carion's avatar
Nicolas Carion committed
31
#include <QToolBar>
32

33
34
35
36
#include <memory>
#include <unordered_set>

class SnapModel;
37
class ProjectClip;
38
class MonitorManager;
39
class QSlider;
40
class QToolButton;
41
class KDualAction;
42
43
class KSelectAction;
class KMessageWidget;
44
class QScrollBar;
45
class RecManager;
46
class QmlManager;
47
class QLabel;
48
class GLWidget;
49
class MonitorAudioLevel;
50
class MonitorProxy;
51
52

namespace Mlt {
Nicolas Carion's avatar
Nicolas Carion committed
53
54
class Profile;
class Filter;
Nicolas Carion's avatar
Nicolas Carion committed
55
} // namespace Mlt
56

57
58
59
60
class QuickEventEater : public QObject
{
    Q_OBJECT
public:
Laurent Montel's avatar
Laurent Montel committed
61
    explicit QuickEventEater(QObject *parent = nullptr);
62
63

protected:
64
    bool eventFilter(QObject *obj, QEvent *event) override;
65
66

signals:
Nicolas Carion's avatar
Nicolas Carion committed
67
    void addEffect(const QStringList &);
Laurent Montel's avatar
Laurent Montel committed
68
    void doKeyPressEvent(QKeyEvent *);
69
70
};

71

72
class Monitor : public AbstractMonitor
73
{
74
75
76
    Q_OBJECT

public:
77
78
    friend class MonitorManager;

Laurent Montel's avatar
Laurent Montel committed
79
    Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *parent = nullptr);
Nicolas Carion's avatar
Nicolas Carion committed
80
    ~Monitor() override;
81
    void resetProfile();
82
83
    /** @brief Rebuild consumers after a property change */
    void resetConsumer(bool fullReset);
Laurent Montel's avatar
Laurent Montel committed
84
    void setCustomProfile(const QString &profile, const Timecode &tc);
Laurent Montel's avatar
Laurent Montel committed
85
    void setupMenu(QMenu *goMenu, QMenu *overlayMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu = nullptr, QAction *loopClip = nullptr);
86
    const QString sceneList(const QString &root, const QString &fullPath = QString(), const QString overlayData = QString());
87
    const QString activeClipId();
88
    int position();
89
    void updateTimecodeFormat();
90
    void updateMarkers();
91
    /** @brief Controller for the clip currently displayed (only valid for clip monitor). */
92
    std::shared_ptr<ProjectClip> currentController() const;
93
    /** @brief Add timeline guides to the ruler and context menu */
Laurent Montel's avatar
Laurent Montel committed
94
    void setGuides(const QMap<double, QString> &guides);
95
    void reloadProducer(const QString &id);
96
    /** @brief Reimplemented from QWidget, updates the palette colors. */
Laurent Montel's avatar
Laurent Montel committed
97
    void setPalette(const QPalette &p);
98
99
100
101
    /** @brief Returns current project's fps. */
    double fps() const;
    /** @brief Get url for the clip's thumbnail */
    QString getMarkerThumb(GenTime pos);
102
103
    int getZoneStart();
    int getZoneEnd();
Vincent Pinon's avatar
Vincent Pinon committed
104
    QPoint getZoneInfo() const;
Laurent Montel's avatar
Laurent Montel committed
105
    void setUpEffectGeometry(const QRect &r, const QVariantList &list = QVariantList(), const QVariantList &types = QVariantList());
106
107
    /** @brief Set a property on the effect scene */
    void setEffectSceneProperty(const QString &name, const QVariant &value);
108
109
    /** @brief Returns effective display size */
    QSize profileSize() const;
110
    QRect effectRect() const;
111
    QVariantList effectPolygon() const;
112
    QVariantList effectRoto() const;
113
    void setEffectKeyframe(bool enable);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
114
    void sendFrameForAnalysis(bool analyse);
115
    void updateAudioForAnalysis();
116
    void switchMonitorInfo(int code);
117
    void restart();
118
    void mute(bool, bool updateIconOnly = false) override;
119
120
    /** @brief Returns the action displaying record toolbar */
    QAction *recAction();
121
    void refreshIcons();
122
    /** @brief Send audio thumb data to qml for on monitor display */
123
    void prepareAudioThumb();
124
    void connectAudioSpectrum(bool activate);
125
126
    /** @brief Set a property on the Qml scene **/
    void setQmlProperty(const QString &name, const QVariant &value);
127
    void displayAudioMonitor(bool isActive);
128
129
    /** @brief Prepare split effect from timeline clip producer **/
    void activateSplit();
130
131
    /** @brief Clear monitor display **/
    void clearDisplay();
132
    void setProducer(std::shared_ptr<Mlt::Producer> producer, int pos = -1);
Nicolas Carion's avatar
Nicolas Carion committed
133
    void reconfigure();
134
    /** @brief Saves current monitor frame to an image file, and add it to project if addToProject is set to true **/
135
    void slotExtractCurrentFrame(QString frameName = QString(), bool addToProject = false);
136
137
138
139
    /** @brief Zoom in active monitor */
    void slotZoomIn();
    /** @brief Zoom out active monitor */
    void slotZoomOut();
140
141
    /** @brief Set a property on the MLT consumer */
    void setConsumerProperty(const QString &name, const QString &value);
142
143
    /** @brief Play or Loop zone sets a fake "out" on the producer. It is necessary to reset this before reloading the producer */
    void resetPlayOrLoopZone(const QString &binId);
144
145
    /** @brief Returns a pointer to monitor proxy, allowing to manage seek and consumer position */
    MonitorProxy *getControllerProxy();
146
147
    /** @brief Update active track in multitrack view */
    void updateMultiTrackView(int tid);
148
149
    /** @brief Returns true if monitor is currently fullscreen */
    bool monitorIsFullScreen() const;
150
    void reloadActiveStream();
151
152
    /** @brief Trigger a refresh of audio thumbs colors */
    void refreshAudioThumbs();
153
154
    /** @brief Trigger a refresh of audio thumbs on notrmalization change */
    void normalizeAudioThumbs();
155
156
    /** @brief Returns true if monitor is playing */
    bool isPlaying() const;
157
158
    /** @brief Enables / disables effect scene*/
    void enableEffectScene(bool enable);
159
    
160

161
protected:
162
163
164
165
166
    void mousePressEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void mouseDoubleClickEvent(QMouseEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void keyPressEvent(QKeyEvent *event) override;
Alberto Villa's avatar
Alberto Villa committed
167
168
169
170
171

    /** @brief Move to another position on mouse wheel event.
     *
     * Moves towards the end of the clip/timeline on mouse wheel down/back, the
     * opposite on mouse wheel up/forward.
172
     * Ctrl + wheel moves by a second, without Ctrl it moves by a single frame. */
173
174
    void wheelEvent(QWheelEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
175
    virtual QStringList mimeTypes() const;
176
    void updateBgColor();
Nicolas Carion's avatar
Nicolas Carion committed
177

178
private:
179
    std::shared_ptr<ProjectClip> m_controller;
180
    /** @brief The QQuickView that handles our monitor display (video and qml overlay) **/
181
    GLWidget *m_glMonitor;
182
    /** @brief Container for our QQuickView monitor display (QQuickView needs to be embedded) **/
183
184
    QWidget *m_glWidget;
    /** @brief Scrollbar for our monitor view, used when zooming the monitor **/
185
    QScrollBar *m_verticalScroll;
186
    /** @brief Scrollbar for our monitor view, used when zooming the monitor **/
187
    QScrollBar *m_horizontalScroll;
188
189
    /** @brief Widget holding the window for the QQuickView **/
    QWidget *m_videoWidget;
190
191
    /** @brief Manager for qml overlay for the QQuickView **/
    QmlManager *m_qmlManager;
192
    std::shared_ptr<SnapModel> m_snaps;
193

194
    std::shared_ptr<Mlt::Filter> m_splitEffect;
195
    std::shared_ptr<Mlt::Producer> m_splitProducer;
196
    int m_length;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
197
    bool m_dragStarted;
198
    RecManager *m_recManager;
199
    /** @brief The widget showing current time position **/
200
    TimecodeDisplay *m_timePos;
201
    KDualAction *m_playAction;
202
    KSelectAction *m_forceSize;
203
204
    /** Has to be available so we can enable and disable it. */
    QAction *m_loopClipAction;
205
    QAction *m_zoomVisibilityAction;
206
    QMenu *m_contextMenu;
207
208
    QMenu *m_configMenu;
    QMenu *m_playMenu;
209
    QMenu *m_markerMenu;
210
    QMenu *m_audioChannels;
211
212
    QToolButton *m_streamsButton;
    QAction *m_streamAction;
213
    QPoint m_DragStartPosition;
214
    /** true if selected clip is transition, false = selected clip is clip.
Laurent Montel's avatar
Laurent Montel committed
215
     *  Necessary because sometimes we get two signals, e.g. we get a clip and we get selected transition = nullptr. */
216
    bool m_loopClipTransition;
217
    GenTime getSnapForPos(bool previous);
218
219
    QToolBar *m_toolbar;
    QSlider *m_audioSlider;
220
    QAction *m_editMarker;
221
    KMessageWidget *m_infoMessage;
222
    int m_forceSizeFactor;
223
    int m_offset;
224
    MonitorSceneType m_lastMonitorSceneType;
225
    MonitorAudioLevel *m_audioMeterWidget;
226
    QTimer m_droppedTimer;
227
    double m_displayedFps;
228
229
    QLabel *m_speedLabel;
    int m_speedIndex;
230
    QMetaObject::Connection m_switchConnection;
231

232
    void adjustScrollBars(float horizontal, float vertical);
233
    void loadQmlScene(MonitorSceneType type, QVariant sceneData = QVariant());
234
    void updateQmlDisplay(int currentOverlay);
235
    /** @brief Create temporary Mlt::Tractor holding a clip and it's effectless clone */
236
    void buildSplitEffect(Mlt::Producer *original);
237
238
    /** @brief Reset and hide speed info label */
    void resetSpeedInfo();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
239

240
private slots:
241
    void slotSetThumbFrame();
242
    void slotSeek();
243
    void updateClipZone(const QPoint zone);
244
    void slotGoToMarker(QAction *action);
245
    void slotSetVolume(int volume);
246
    void slotEditMarker();
247
    void slotExtractCurrentZone();
Laurent Montel's avatar
Laurent Montel committed
248
    void onFrameDisplayed(const SharedFrame &frame);
249
    void slotStartDrag();
250
    void setZoom();
251
    void slotAdjustEffectCompare();
252
    void slotShowMenu(const QPoint pos);
253
    void slotForceSize(QAction *a);
254
    void slotSeekToKeyFrame();
255
    /** @brief Display a non blocking error message to user **/
Laurent Montel's avatar
Laurent Montel committed
256
    void warningMessage(const QString &text, int timeout = 5000, const QList<QAction *> &actions = QList<QAction *>());
257
    void slotLockMonitor(bool lock);
258
    void slotAddEffect(const QStringList &effect);
Vincent Pinon's avatar
Vincent Pinon committed
259
    void slotSwitchPlay();
260
    void slotEditInlineMarker();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
261
    /** @brief Pass keypress event to mainwindow */
Laurent Montel's avatar
Laurent Montel committed
262
    void doKeyPressEvent(QKeyEvent *);
263
264
    /** @brief There was an error initializing Movit */
    void gpuError();
265
266
    void setOffsetX(int x);
    void setOffsetY(int y);
267
268
    /** @brief Pan monitor view */
    void panView(QPoint diff);
269
    void slotSeekPosition(int);
270
271
    void addSnapPoint(int pos);
    void removeSnapPoint(int pos);
272
    /** @brief Process seek and optionally pause monitor */
273
    void processSeek(int pos);
274
275
    /** @brief Check and display dropped frames */
    void checkDrops();
276
277
    /** @brief En/Disable the show record timecode feature in clip monitor */
    void slotSwitchRecTimecode(bool enable);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
278

279
public slots:
280
    void slotSetScreen(int screenIndex);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
281
    void slotOpenDvdFile(const QString &);
282
    void slotPreviewResource(const QString &path, const QString &title);
Nicolas Carion's avatar
Nicolas Carion committed
283
    // void slotSetClipProducer(DocClipBase *clip, QPoint zone = QPoint(), bool forceUpdate = false, int position = -1);
Nicolas Carion's avatar
Nicolas Carion committed
284
    void updateClipProducer(const std::shared_ptr<Mlt::Producer> &prod);
285
    void updateClipProducer(const QString &playlist);
Nicolas Carion's avatar
Nicolas Carion committed
286
    void slotOpenClip(const std::shared_ptr<ProjectClip> &controller, int in = -1, int out = -1);
287
    void slotRefreshMonitor(bool visible);
288
    void slotSeek(int pos);
289
290
    void stop() override;
    void start() override;
291
    void switchPlay(bool play);
292
    void updatePlayAction(bool play);
293
    void slotPlay() override;
294
    void pause();
295
296
    void slotPlayZone();
    void slotLoopZone();
297
    /** @brief Loops the selected item (clip or transition). */
298
    void slotLoopClip(QPoint inOut);
299
    void slotForward(double speed = 0, bool allowNormalPlay = false) override;
300
    void slotRewind(double speed = 0) override;
301
302
    void slotRewindOneFrame(int diff = 1);
    void slotForwardOneFrame(int diff = 1);
303
304
    void slotStart();
    void slotEnd();
305
    void slotSetZoneStart();
306
    void slotSetZoneEnd();
307
308
    void slotZoneStart();
    void slotZoneEnd();
309
    void slotLoadClipZone(const QPoint &zone);
310
311
    void slotSeekToNextSnap();
    void slotSeekToPreviousSnap();
Nicolas Carion's avatar
Nicolas Carion committed
312
    void adjustRulerSize(int length, const std::shared_ptr<MarkerListModel> &markerModel = nullptr);
313
    void setTimePos(const QString &pos);
314
    /** @brief Display the on monitor effect scene (to adjust geometry over monitor). */
315
    void slotShowEffectScene(MonitorSceneType sceneType, bool temporary = false, QVariant sceneData = QVariant());
316
    bool effectSceneDisplayed(MonitorSceneType effectType);
317
    /** @brief split screen to compare clip with and without effect */
318
    void slotSwitchCompare(bool enable);
319
    void slotMouseSeek(int eventDelta, uint modifiers) override;
320
    void slotSwitchFullScreen(bool minimizeOnly = false) override;
321
322
    /** @brief Display or hide the record toolbar */
    void slotSwitchRec(bool enable);
323
    /** @brief Request QImage of current frame */
324
    void slotGetCurrentImage(bool request);
325
326
    /** @brief Enable/disable display of monitor's audio levels widget */
    void slotSwitchAudioMonitor();
327
328
    /** @brief Request seeking */
    void requestSeek(int pos);
329
330
    /** @brief Check current position to show relevant infos in qml view (markers, zone in/out, etc). */
    void checkOverlay(int pos = -1);
331
    void refreshMonitorIfActive(bool directUpdate = false) override;
332
    void forceMonitorRefresh();
333
334
    /** @brief Clear read ahead cache, to ensure up to date audio */
    void purgeCache();
Nicolas Carion's avatar
Nicolas Carion committed
335

336
signals:
337
    void screenChanged(int screenIndex);
338
339
    void seekPosition(int pos);
    void updateScene();
340
    void durationChanged(int);
341
    void refreshClipThumbnail(const QString &);
Laurent Montel's avatar
Laurent Montel committed
342
    void zoneUpdated(const QPoint &);
343
    void zoneUpdatedWithUndo(const QPoint &, const QPoint &);
344
    /** @brief  Editing transitions / effects over the monitor requires the renderer to send frames as QImage.
345
346
     *      This causes a major slowdown, so we only enable it if required */
    void requestFrameForAnalysis(bool);
Laurent Montel's avatar
Laurent Montel committed
347
348
    void effectChanged(const QRect &);
    void effectPointsChanged(const QVariantList &);
349
    void addRemoveKeyframe();
350
351
    void seekToNextKeyframe();
    void seekToPreviousKeyframe();
352
    void seekToKeyframe(int);
Laurent Montel's avatar
Laurent Montel committed
353
    void addClipToProject(const QUrl &);
354
355
    /** @brief Request display of current bin clip. */
    void refreshCurrentClip();
356
357
    void addEffect(const QStringList &);
    void addMasterEffect(QString, const QStringList &);
Laurent Montel's avatar
Laurent Montel committed
358
    void passKeyPress(QKeyEvent *);
359
    /** @brief Enable / disable project monitor multitrack view (split view with one track in each quarter). */
360
    void multitrackView(bool, bool);
Laurent Montel's avatar
Laurent Montel committed
361
    void timeCodeUpdated(const QString &);
362
    void addMarker();
363
364
365
    void deleteMarker(bool deleteGuide = true);
    void seekToPreviousSnap();
    void seekToNextSnap();
366
    void createSplitOverlay(std::shared_ptr<Mlt::Filter>);
367
    void removeSplitOverlay();
368
    void acceptRipple(bool);
369
    void switchTrimMode(int);
370
    void activateTrack(int);
371
    void autoKeyframeChanged();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
372
373
374
};

#endif