glwidget.h 7.16 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * Copyright (c) 2011-2014 Meltytech, LLC
 * Author: Dan Dennedy <dan@dennedy.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 3 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, see <http://www.gnu.org/licenses/>.
 */

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QSemaphore>
#include <QQuickView>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QOpenGLContext>
28
#include <QOffscreenSurface>
29
30
31
#include <QMutex>
#include <QThread>
#include <QRect>
32

33
#include "scopes/sharedframe.h"
34
#include "definitions.h"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

class QOpenGLFunctions_3_2_Core;
//class QmlFilter;
//class QmlMetadata;

namespace Mlt {
class Filter;
}

class RenderThread;
class FrameRenderer;


typedef void* ( *thread_function_t )( void* );

class GLWidget : public QQuickView, protected QOpenGLFunctions
{
    Q_OBJECT
    Q_PROPERTY(QRect rect READ rect NOTIFY rectChanged)
    Q_PROPERTY(float zoom READ zoom NOTIFY zoomChanged)
    Q_PROPERTY(QPoint offset READ offset NOTIFY offsetChanged)

public:
58
    GLWidget(int id, QObject *parent = 0);
59
60
61
62
63
    ~GLWidget();

    void createThread(RenderThread** thread, thread_function_t function, void* data);
    void startGlsl();
    void stopGlsl();
64
    void clear();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
65
    /** @brief Update producer, should ONLY be called from renderer.cpp */
Vincent Pinon's avatar
Vincent Pinon committed
66
    int setProducer(Mlt::Producer* producer);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
67
68
69
    int reconfigureMulti(QString params, QString path, Mlt::Profile *profile);
    void stopCapture();
    int reconfigure(Mlt::Profile *profile = NULL);
70
71

    int displayWidth() const { return m_rect.width(); }
72
    void updateAudioForAnalysis();
73
74
75
76
77
    int displayHeight() const { return m_rect.height(); }

    QObject* videoWidget() { return this; }
    Mlt::Filter* glslManager() const { return m_glslManager; }
    QRect rect() const { return m_rect; }
78
79
    QRect effectRect() const { return m_effectRect; }
    float zoom() const;
80
    float scale() const;
81
82
83
    QPoint offset() const;
    Mlt::Consumer *consumer();
    Mlt::Producer *producer();
84
    QSize profileSize() const;
85
    QRect displayRect() const;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
86
87
    /** @brief set to true if we want to emit a QImage of the frame for analysis */
    bool sendFrameForAnalysis;
88
    void updateGamma();
89
90
    Mlt::Profile *profile();
    void resetProfile(MltVideoProfile profile);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
91
    void reloadProfile(Mlt::Profile &profile);
92
93
    void lockMonitor();
    void releaseMonitor();
94
    int realTime() const;
95
    void setAudioThumb(int channels = 0, QVariantList audioCache = QList<QVariant>());
96
97
    int droppedFrames() const;
    void resetDrops();
98

99
100
101
102
103
104
105
protected:
    void mouseReleaseEvent(QMouseEvent * event);
    void mouseDoubleClickEvent(QMouseEvent * event);
    void wheelEvent(QWheelEvent * event);

public slots:
    void setZoom(float zoom);
106
107
    void setOffsetX(int x, int max);
    void setOffsetY(int y, int max);
108
    void slotSwitchAudioOverlay(bool enable);
109
    void slotZoomScene(double value);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
110
    void initializeGL();
111
    void releaseAnalyse();
112

113
114
115
116
117
118
119
120
121
122
123
124
125
signals:
    void frameDisplayed(const SharedFrame& frame);
    void textureUpdated();
    void dragStarted();
    void seekTo(int x);
    void gpuNotSupported();
    void started();
    void paused();
    void playing();
    void rectChanged();
    void zoomChanged();
    void offsetChanged();
    void monitorPlay();
126
    void switchFullScreen(bool minimizeOnly = false);
127
    void mouseSeek(int eventDelta, int modifiers);
128
    void startDrag();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
129
    void analyseFrame(QImage);
130
    void audioSamplesSignal(const audioShortVector&,int,int,int);
131
    void showContextMenu(const QPoint);
132
    void lockMonitor(bool);
133
    void passKeyEvent(QKeyEvent *);
134
    void panView(QPoint diff);
135
136

private:
137
    int m_id;
138
    QRect m_rect;
139
    QRect m_effectRect;
140
141
    GLuint m_texture[3];
    QOpenGLShaderProgram* m_shader;
142
    QPoint m_panStart;
143
144
145
146
147
    QPoint m_dragStart;
    Mlt::Filter* m_glslManager;
    Mlt::Consumer* m_consumer;
    Mlt::Producer* m_producer;
    QSemaphore m_initSem;
148
    QSemaphore m_analyseSem;
149
150
151
152
153
    bool m_isInitialized;
    Mlt::Event* m_threadStartEvent;
    Mlt::Event* m_threadStopEvent;
    Mlt::Event* m_threadCreateEvent;
    Mlt::Event* m_threadJoinEvent;
154
    Mlt::Event* m_displayEvent;
155
    Mlt::Profile *m_monitorProfile;
156
157
158
159
160
161
162
163
    FrameRenderer* m_frameRenderer;
    int m_projectionLocation;
    int m_modelViewLocation;
    int m_vertexLocation;
    int m_texCoordLocation;
    int m_colorspaceLocation;
    int m_textureLocation[3];
    float m_zoom;
164
    bool m_openGLSync;
165
166
    SharedFrame m_sharedFrame;
    QMutex m_mutex;
167
    QPoint m_offset;
168
    QOffscreenSurface m_offscreenSurface;
169
    QOpenGLContext* m_shareContext;
170
    bool m_audioWaveDisplayed;
171
    static void on_frame_show(mlt_consumer, void* self, mlt_frame frame);
172
    static void on_gl_frame_show(mlt_consumer, void* self, mlt_frame frame_ptr);
173
    static void on_gl_nosync_frame_show(mlt_consumer, void* self, mlt_frame frame_ptr);
174
175
176
    void createAudioOverlay(bool isAudio);
    void removeAudioOverlay();
    void adjustAudioOverlay(bool isAudio);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
177
    QOpenGLFramebufferObject *m_fbo;
178
    void refreshSceneLayout();
179
180
181
182
183

private slots:
    void resizeGL(int width, int height);
    void updateTexture(GLuint yName, GLuint uName, GLuint vName);
    void paintGL();
184
    void onFrameDisplayed(const SharedFrame &frame);
185
    void createOffscreen();
186
187
188
189
190
191
192
193
194
195
196
197
198

protected:
    void resizeEvent(QResizeEvent* event);
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void keyPressEvent(QKeyEvent* event);
    void createShader();
};

class RenderThread : public QThread
{
    Q_OBJECT
public:
199
    RenderThread(thread_function_t function, void* data, QOpenGLContext *context, QSurface *surface);
200
    ~RenderThread();
201
202
203
204
205
206
207
208

protected:
    void run();

private:
    thread_function_t m_function;
    void* m_data;
    QOpenGLContext* m_context;
209
    QSurface* m_surface;
210
211
212
213
214
215
};

class FrameRenderer : public QThread
{
    Q_OBJECT
public:
216
    explicit FrameRenderer(QOpenGLContext* shareContext, QSurface *surface);
217
218
219
    ~FrameRenderer();
    QSemaphore* semaphore() { return &m_semaphore; }
    QOpenGLContext* context() const { return m_context; }
220
    void clearFrame();
221
    Q_INVOKABLE void showFrame(Mlt::Frame frame);
222
    Q_INVOKABLE void showGLFrame(Mlt::Frame frame);
223
    Q_INVOKABLE void showGLNoSyncFrame(Mlt::Frame frame);
224
225
226
227
228
229
230

public slots:
    void cleanup();

signals:
    void textureReady(GLuint yName, GLuint uName = 0, GLuint vName = 0);
    void frameDisplayed(const SharedFrame& frame);
231
    void audioSamplesSignal(const audioShortVector&,int,int,int);
232
233
234
235

private:
    QSemaphore m_semaphore;
    SharedFrame m_frame;
236
    SharedFrame m_displayFrame;
237
    QOpenGLContext* m_context;
238
    QSurface* m_surface;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
239

240
241
242
243
public:
    GLuint m_renderTexture[3];
    GLuint m_displayTexture[3];
    QOpenGLFunctions_3_2_Core* m_gl32;
244
    bool sendAudioForAnalysis;
245
246
247
248
249
};



#endif