CuteLogger
Fast and simple logging solution for Qt based applications
videowidget.h
1 /*
2  * Copyright (c) 2011-2023 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 VIDEOWIDGET_H
19 #define VIDEOWIDGET_H
20 
21 #include <QSemaphore>
22 #include <QQuickWidget>
23 #include <QMutex>
24 #include <QThread>
25 #include <QRectF>
26 #include <QTimer>
27 #include "mltcontroller.h"
28 #include "sharedframe.h"
29 
30 class QmlFilter;
31 class QmlMetadata;
32 class QOpenGLContext;
33 class QOffscreenSurface;
34 
35 namespace Mlt {
36 
37 class Filter;
38 class RenderThread;
39 class FrameRenderer;
40 
41 typedef void *(*thread_function_t )( void * );
42 
43 class VideoWidget : public QQuickWidget, public Controller
44 {
45  Q_OBJECT
46  Q_PROPERTY(QRectF rect READ rect NOTIFY rectChanged)
47  Q_PROPERTY(int grid READ grid NOTIFY gridChanged)
48  Q_PROPERTY(bool snapToGrid READ snapToGrid NOTIFY snapToGridChanged)
49  Q_PROPERTY(float zoom READ zoom NOTIFY zoomChanged)
50  Q_PROPERTY(QPoint offset READ offset NOTIFY offsetChanged)
51 
52 public:
53  VideoWidget(QObject *parent = 0);
54  virtual ~VideoWidget();
55 
56  int setProducer(Mlt::Producer *, bool isMulti = false);
57  void createThread(RenderThread **thread, thread_function_t function, void *data);
58  void startGlsl();
59  void stopGlsl();
60  int reconfigure(bool isMulti);
61 
62  void play(double speed = 1.0)
63  {
64  Controller::play(speed);
65  if (speed == 0) emit paused();
66  else emit playing();
67  }
68  void seek(int position)
69  {
70  Controller::seek(position);
71  emit paused();
72  }
73  void refreshConsumer(bool scrubAudio = false);
74  void pause()
75  {
76  Controller::pause();
77  emit paused();
78  }
79  int displayWidth() const
80  {
81  return m_rect.width();
82  }
83  int displayHeight() const
84  {
85  return m_rect.height();
86  }
87 
88  QObject *videoWidget()
89  {
90  return this;
91  }
92  QRectF rect() const
93  {
94  return m_rect;
95  }
96  int grid() const
97  {
98  return m_grid;
99  }
100  float zoom() const
101  {
102  return m_zoom * MLT.profile().width() / m_rect.width();
103  }
104  QPoint offset() const;
105  QImage image() const;
106  bool imageIsProxy() const;
107  void requestImage() const;
108  bool snapToGrid() const
109  {
110  return m_snapToGrid;
111  }
112  int maxTextureSize() const
113  {
114  return m_maxTextureSize;
115  }
116 
117 public slots:
118  void setGrid(int grid);
119  void setZoom(float zoom);
120  void setOffsetX(int x);
121  void setOffsetY(int y);
122  void setBlankScene();
123  void setCurrentFilter(QmlFilter *filter, QmlMetadata *meta);
124  void setSnapToGrid(bool snap);
125  virtual void initialize();
126  virtual void beforeRendering() {};
127  virtual void renderVideo();
128  virtual void onFrameDisplayed(const SharedFrame &frame);
129 
130 signals:
131  void frameDisplayed(const SharedFrame &frame);
132  void dragStarted();
133  void seekTo(int x);
134  void gpuNotSupported();
135  void started();
136  void paused();
137  void playing();
138  void rectChanged();
139  void gridChanged();
140  void zoomChanged();
141  void offsetChanged(const QPoint &offset = QPoint());
142  void imageReady();
143  void snapToGridChanged();
144  void toggleZoom(bool);
145 
146 private:
147  QRectF m_rect;
148  int m_grid;
149  QPoint m_dragStart;
150  QSemaphore m_initSem;
151  bool m_isInitialized;
152  std::unique_ptr<Filter> m_glslManager;
153  std::unique_ptr<Event> m_threadStartEvent;
154  std::unique_ptr<Event> m_threadStopEvent;
155  std::unique_ptr<Event> m_threadCreateEvent;
156  std::unique_ptr<Event> m_threadJoinEvent;
157  FrameRenderer *m_frameRenderer;
158  float m_zoom;
159  QPoint m_offset;
160  QUrl m_savedQmlSource;
161  bool m_snapToGrid;
162  QTimer m_refreshTimer;
163  bool m_scrubAudio;
164  QPoint m_mousePosition;
165  std::unique_ptr<RenderThread> m_renderThread;
166 
167  static void on_frame_show(mlt_consumer, VideoWidget *widget, mlt_event_data);
168 
169 private slots:
170  void resizeVideo(int width, int height);
171  void onRefreshTimeout();
172 
173 protected:
174  void resizeEvent(QResizeEvent *event);
175  void mousePressEvent(QMouseEvent *);
176  void mouseMoveEvent(QMouseEvent *);
177  void keyPressEvent(QKeyEvent *event);
178  bool event(QEvent *event);
179  void createShader();
180 
181  int m_maxTextureSize;
182  SharedFrame m_sharedFrame;
183  QMutex m_mutex;
184 };
185 
186 class RenderThread : public QThread
187 {
188  Q_OBJECT
189 public:
190  RenderThread(thread_function_t function, void *data);
191  ~RenderThread();
192 
193 protected:
194  void run();
195 
196 private:
197  thread_function_t m_function;
198  void *m_data;
199  std::unique_ptr<QOpenGLContext> m_context;
200  std::unique_ptr<QOffscreenSurface> m_surface;
201 };
202 
203 class FrameRenderer : public QThread
204 {
205  Q_OBJECT
206 public:
207  FrameRenderer();
208  ~FrameRenderer();
209  QSemaphore *semaphore()
210  {
211  return &m_semaphore;
212  }
213  SharedFrame getDisplayFrame();
214  Q_INVOKABLE void showFrame(Mlt::Frame frame);
215  void requestImage();
216  QImage image() const
217  {
218  return m_image;
219  }
220 
221 signals:
222  void frameDisplayed(const SharedFrame &frame);
223  void imageReady();
224 
225 private:
226  QSemaphore m_semaphore;
227  SharedFrame m_displayFrame;
228  bool m_imageRequested;
229  QImage m_image;
230 };
231 
232 } // namespace
233 
234 #endif
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition: sharedframe.h:49