CuteLogger
Fast and simple logging solution for Qt based applications
glwidget.h
1 /*
2  * Copyright (c) 2011-2020 Meltytech, LLC
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GLWIDGET_H
19 #define GLWIDGET_H
20 
21 #include <QSemaphore>
22 #include <QQuickWidget>
23 #include <QOpenGLFunctions>
24 #include <QOpenGLShaderProgram>
25 #include <QOpenGLFramebufferObject>
26 #include <QOpenGLContext>
27 #include <QOffscreenSurface>
28 #include <QMutex>
29 #include <QThread>
30 #include <QRectF>
31 #include <QTimer>
32 #include "mltcontroller.h"
33 #include "sharedframe.h"
34 
35 class QOpenGLFunctions_3_2_Core;
36 class QOpenGLTexture;
37 class QmlFilter;
38 class QmlMetadata;
39 
40 namespace Mlt {
41 
42 class Filter;
43 class RenderThread;
44 class FrameRenderer;
45 
46 typedef void* ( *thread_function_t )( void* );
47 
48 class GLWidget : public QQuickWidget, public Controller, protected QOpenGLFunctions
49 {
50  Q_OBJECT
51  Q_PROPERTY(QRectF rect READ rect NOTIFY rectChanged)
52  Q_PROPERTY(int grid READ grid NOTIFY gridChanged)
53  Q_PROPERTY(bool snapToGrid READ snapToGrid NOTIFY snapToGridChanged)
54  Q_PROPERTY(float zoom READ zoom NOTIFY zoomChanged)
55  Q_PROPERTY(QPoint offset READ offset NOTIFY offsetChanged)
56 
57 public:
58  GLWidget(QObject *parent = 0);
59  ~GLWidget();
60 
61  void createThread(RenderThread** thread, thread_function_t function, void* data);
62  void startGlsl();
63  void stopGlsl();
64  int setProducer(Mlt::Producer*, bool isMulti = false);
65  int reconfigure(bool isMulti);
66 
67  void play(double speed = 1.0) {
68  Controller::play(speed);
69  if (speed == 0) emit paused();
70  else emit playing();
71  }
72  void seek(int position) {
73  Controller::seek(position);
74  emit paused();
75  }
76  void refreshConsumer(bool scrubAudio = false);
77  void pause() {
78  Controller::pause();
79  emit paused();
80  }
81  int displayWidth() const { return m_rect.width(); }
82  int displayHeight() const { return m_rect.height(); }
83 
84  QObject* videoWidget() { return this; }
85  Filter* glslManager() const { return m_glslManager; }
86  QRectF rect() const { return m_rect; }
87  int grid() const { return m_grid; }
88  float zoom() const { return m_zoom * MLT.profile().width() / m_rect.width(); }
89  QPoint offset() const;
90  QImage image() const;
91  bool imageIsProxy() const;
92  void requestImage() const;
93  bool snapToGrid() const { return m_snapToGrid; }
94  int maxTextureSize() const { return m_maxTextureSize; }
95 
96 public slots:
97  void onFrameDisplayed(const SharedFrame& frame);
98  void setGrid(int grid);
99  void setZoom(float zoom);
100  void setOffsetX(int x);
101  void setOffsetY(int y);
102  void setBlankScene();
103  void setCurrentFilter(QmlFilter* filter, QmlMetadata* meta);
104  void setSnapToGrid(bool snap);
105 
106 signals:
107  void frameDisplayed(const SharedFrame& frame);
108  void dragStarted();
109  void seekTo(int x);
110  void gpuNotSupported();
111  void started();
112  void paused();
113  void playing();
114  void rectChanged();
115  void gridChanged();
116  void zoomChanged();
117  void offsetChanged();
118  void imageReady();
119  void snapToGridChanged();
120  void toggleZoom(bool);
121 
122 private:
123  QRectF m_rect;
124  int m_grid;
125  GLuint m_texture[3];
126  QOpenGLShaderProgram* m_shader;
127  QPoint m_dragStart;
128  Filter* m_glslManager;
129  QSemaphore m_initSem;
130  bool m_isInitialized;
131  Event* m_threadStartEvent;
132  Event* m_threadStopEvent;
133  Event* m_threadCreateEvent;
134  Event* m_threadJoinEvent;
135  FrameRenderer* m_frameRenderer;
136  int m_projectionLocation;
137  int m_modelViewLocation;
138  int m_vertexLocation;
139  int m_texCoordLocation;
140  int m_colorspaceLocation;
141  int m_textureLocation[3];
142  float m_zoom;
143  QPoint m_offset;
144  QOffscreenSurface m_offscreenSurface;
145  QOpenGLContext* m_shareContext;
146  SharedFrame m_sharedFrame;
147  QMutex m_mutex;
148  QUrl m_savedQmlSource;
149  bool m_snapToGrid;
150  QTimer m_refreshTimer;
151  bool m_scrubAudio;
152  GLint m_maxTextureSize;
153 
154  static void on_frame_show(mlt_consumer, GLWidget* widget, mlt_event_data);
155 
156 private slots:
157  void initializeGL();
158  void resizeGL(int width, int height);
159  void updateTexture(GLuint yName, GLuint uName, GLuint vName);
160  void paintGL();
161  void onRefreshTimeout();
162 
163 protected:
164  void resizeEvent(QResizeEvent* event);
165  void mousePressEvent(QMouseEvent *);
166  void mouseMoveEvent(QMouseEvent *);
167  void keyPressEvent(QKeyEvent* event);
168  bool event(QEvent* event);
169  void createShader();
170 };
171 
172 class RenderThread : public QThread
173 {
174  Q_OBJECT
175 public:
176  RenderThread(thread_function_t function, void* data, QOpenGLContext *context, QSurface* surface);
177 
178 protected:
179  void run();
180 
181 private:
182  thread_function_t m_function;
183  void* m_data;
184  QOpenGLContext* m_context;
185  QSurface* m_surface;
186 };
187 
188 class FrameRenderer : public QThread
189 {
190  Q_OBJECT
191 public:
192  FrameRenderer(QOpenGLContext* shareContext, QSurface* surface);
193  ~FrameRenderer();
194  QSemaphore* semaphore() { return &m_semaphore; }
195  QOpenGLContext* context() const { return m_context; }
196  SharedFrame getDisplayFrame();
197  Q_INVOKABLE void showFrame(Mlt::Frame frame);
198  void requestImage();
199  QImage image() const { return m_image; }
200 
201 public slots:
202  void cleanup();
203 
204 signals:
205  void textureReady(GLuint yName, GLuint uName = 0, GLuint vName = 0);
206  void frameDisplayed(const SharedFrame& frame);
207  void imageReady();
208 
209 private:
210  QSemaphore m_semaphore;
211  SharedFrame m_displayFrame;
212  QOpenGLContext* m_context;
213  QSurface* m_surface;
214  qint64 m_previousMSecs;
215  bool m_imageRequested;
216  QImage m_image;
217 
218 public:
219  GLuint m_renderTexture[3];
220  GLuint m_displayTexture[3];
221  QOpenGLFunctions_3_2_Core* m_gl32;
222 };
223 
224 } // namespace
225 
226 #endif
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition: sharedframe.h:49