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