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