21#include "mltcontroller.h"
23#include "sharedframe.h"
25enum class HdrTransfer { SDR = 0, HLG = 1, PQ = 2 };
27inline HdrTransfer hdrTransferFromTrc(
const QString &trc)
29 if (trc == QLatin1String(
"arib-std-b67"))
30 return HdrTransfer::HLG;
31 if (trc == QLatin1String(
"smpte2084"))
32 return HdrTransfer::PQ;
33 return HdrTransfer::SDR;
37#include <QAbstractVideoBuffer>
40#include <QQuickWidget>
46#include <QVideoFrameFormat>
52class QOffscreenSurface;
60typedef void *(*thread_function_t)(
void *);
62class VideoWidget :
public QQuickWidget,
public Controller
65 Q_PROPERTY(QRectF rect READ rect NOTIFY rectChanged)
66 Q_PROPERTY(
int grid READ grid NOTIFY gridChanged)
67 Q_PROPERTY(
bool snapToGrid READ snapToGrid NOTIFY snapToGridChanged)
68 Q_PROPERTY(
float zoom READ zoom NOTIFY zoomChanged)
69 Q_PROPERTY(QPoint offset READ offset NOTIFY offsetChanged)
70 Q_PROPERTY(
bool oldVideoOutput READ oldVideoOutput CONSTANT)
73 VideoWidget(QObject *parent = 0);
74 virtual ~VideoWidget();
76 int setProducer(Mlt::Producer *,
bool isMulti =
false)
override;
77 void createThread(RenderThread **thread, thread_function_t function,
void *data);
80 int reconfigure(
bool isMulti)
override;
82 void play(
double speed = 1.0)
override
84 Controller::play(speed);
90 void seek(
int position)
override
92 Controller::seek(position);
93 if (Settings.playerPauseAfterSeek())
96 void refreshConsumer(
bool scrubAudio =
false)
override;
97 void pause(
int position = -1)
override
102 int displayWidth()
const override {
return m_rect.width(); }
103 int displayHeight()
const override {
return m_rect.height(); }
105 QObject *videoWidget()
override {
return this; }
106 QRectF rect()
const {
return m_rect; }
107 int grid()
const {
return m_grid; }
110 return m_zoom * MLT.profile().height() * MLT.profile().dar() / m_rect.width();
112 QPoint offset()
const;
113 QImage image()
const;
114 bool imageIsProxy()
const;
116 bool snapToGrid()
const {
return m_snapToGrid; }
117 int maxTextureSize()
const {
return m_maxTextureSize; }
118 bool oldVideoOutput()
const;
119 void toggleVuiDisplay();
120 Q_INVOKABLE
void setVideoSink(QVideoSink *sink);
123 void setGrid(
int grid);
124 void setZoom(
float zoom);
125 void setOffsetX(
int x);
126 void setOffsetY(
int y);
127 void setBlankScene();
128 void setCurrentFilter(QmlFilter *filter, QmlMetadata *meta);
129 void setSnapToGrid(
bool snap);
130 virtual void initialize();
131 virtual void beforeRendering() {}
132 virtual void renderVideo();
133 virtual void onFrameDisplayed(
const SharedFrame &frame);
134 void showFrame(Mlt::Frame frame, QByteArray p016Buffer = {});
137 void frameDisplayed(
const SharedFrame &frame);
140 void gpuNotSupported();
147 void offsetChanged(
const QPoint &offset = QPoint());
149 void snapToGridChanged();
150 void toggleZoom(
bool);
151 void stepZoom(
float,
float);
152 void videoFrameReady(
const QVideoFrame &frame);
153 void hdrTransferChanged(HdrTransfer transfer);
159 QSemaphore m_initSem;
160 bool m_isInitialized;
161 std::unique_ptr<Filter> m_glslManager;
162 std::unique_ptr<Event> m_threadStartEvent;
163 std::unique_ptr<Event> m_threadStopEvent;
164 std::unique_ptr<Event> m_threadCreateEvent;
165 std::unique_ptr<Event> m_threadJoinEvent;
166 QSemaphore m_frameSemaphore;
167 bool m_imageRequested;
168 const bool m_oldVideoOutput;
171 QUrl m_savedQmlSource;
174 QTimer m_refreshTimer;
176 QPoint m_mousePosition;
177 std::unique_ptr<RenderThread> m_renderThread;
178 QPointer<QVideoSink> m_videoSink;
179 FrameRenderer *m_frameRenderer;
181 static void on_frame_show(mlt_consumer, VideoWidget *widget, mlt_event_data);
182 void pushFrameToSink(
const SharedFrame &frame, QByteArray p016Buffer = {});
186 QList<QByteArray> buffers;
188 std::shared_ptr<P016Pool> m_p016Pool;
191 void resizeVideo(
int width,
int height);
192 void onRefreshTimeout();
195 void resizeEvent(QResizeEvent *event)
override;
196 void mousePressEvent(QMouseEvent *)
override;
197 void mouseMoveEvent(QMouseEvent *)
override;
198 void wheelEvent(QWheelEvent *event)
override;
199 void keyPressEvent(QKeyEvent *event)
override;
200 bool event(QEvent *event)
override;
201 virtual void createShader() {}
203 int m_maxTextureSize;
204 SharedFrame m_sharedFrame;
208class RenderThread :
public QThread
212 RenderThread(thread_function_t function,
void *data);
219 thread_function_t m_function;
221 std::unique_ptr<QOpenGLContext> m_context;
222 std::unique_ptr<QOffscreenSurface> m_surface;
225class FrameRenderer :
public QThread
231 QSemaphore *semaphore() {
return &m_semaphore; }
232 SharedFrame getDisplayFrame();
233 Q_INVOKABLE
void showFrame(Mlt::Frame frame);
235 QImage image()
const {
return m_image; }
238 void frameDisplayed(
const SharedFrame &frame);
242 QSemaphore m_semaphore;
243 mutable QMutex m_mutex;
244 SharedFrame m_displayFrame;
245 bool m_imageRequested;