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
30class QmlFilter;
31class QmlMetadata;
32class QOpenGLContext;
33class QOffscreenSurface;
34
35namespace Mlt {
36
37class Filter;
38class RenderThread;
39class FrameRenderer;
40
41typedef void *( *thread_function_t )( void * );
42
43class 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
52public:
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
117public 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
130signals:
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
146private:
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
169private slots:
170 void resizeVideo(int width, int height);
171 void onRefreshTimeout();
172
173protected:
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
186class RenderThread : public QThread
187{
188 Q_OBJECT
189public:
190 RenderThread(thread_function_t function, void *data);
191 ~RenderThread();
192
193protected:
194 void run();
195
196private:
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
203class FrameRenderer : public QThread
204{
205 Q_OBJECT
206public:
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
221signals:
222 void frameDisplayed(const SharedFrame &frame);
223 void imageReady();
224
225private:
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