Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickvideooutput_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2016 Research In Motion
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QQUICKVIDEOOUTPUT_P_H
6#define QQUICKVIDEOOUTPUT_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qrect.h>
20#include <QtCore/qpointer.h>
21#include <QtCore/qmutex.h>
22#include <QtQuick/qquickitem.h>
23
24#include <QtMultimedia/qvideoframe.h>
25#include <QtMultimedia/qvideoframeformat.h>
26#include <QtMultimedia/qvideosink.h>
27#include <QtMultimediaQuick/private/qtmultimediaquickglobal_p.h>
28
29#include <thread>
30
31QT_BEGIN_NAMESPACE
32
33class QQuickVideoBackend;
34class QVideoOutputOrientationHandler;
35class QVideoSink;
36class QSGVideoNode;
37class QVideoFrameTexturePool;
38using QVideoFrameTexturePoolWPtr = std::weak_ptr<QVideoFrameTexturePool>;
39
41{
42 Q_OBJECT
43 QML_NAMED_ELEMENT(VideoSink)
44public:
50
53};
54
55class Q_MULTIMEDIAQUICK_EXPORT QQuickVideoOutput : public QQuickItem
56{
57 Q_OBJECT
58 Q_DISABLE_COPY(QQuickVideoOutput)
59 Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
60 Q_PROPERTY(EndOfStreamPolicy endOfStreamPolicy READ endOfStreamPolicy WRITE setEndOfStreamPolicy
61 NOTIFY endOfStreamPolicyChanged REVISION(6, 9))
62 Q_PROPERTY(int orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
63 Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION(6, 9))
64 Q_PROPERTY(QRectF sourceRect READ sourceRect NOTIFY sourceRectChanged)
65 Q_PROPERTY(QRectF contentRect READ contentRect NOTIFY contentRectChanged)
66 Q_PROPERTY(QVideoSink* videoSink READ videoSink CONSTANT)
67 Q_MOC_INCLUDE(qvideosink.h)
68 Q_MOC_INCLUDE(qvideoframe.h)
69 QML_NAMED_ELEMENT(VideoOutput)
70
71public:
72
73 enum FillMode
74 {
75 Stretch = Qt::IgnoreAspectRatio,
76 PreserveAspectFit = Qt::KeepAspectRatio,
77 PreserveAspectCrop = Qt::KeepAspectRatioByExpanding
78 };
79 Q_ENUM(FillMode)
80
81 enum EndOfStreamPolicy
82 {
83 ClearOutput,
84 KeepLastFrame
85 };
86 Q_ENUM(EndOfStreamPolicy)
87
88 QQuickVideoOutput(QQuickItem *parent = 0);
89 ~QQuickVideoOutput() override;
90
91 Q_INVOKABLE QVideoSink *videoSink() const;
92
93 FillMode fillMode() const;
94 void setFillMode(FillMode mode);
95
96 int orientation() const;
97 void setOrientation(int);
98
99 bool mirrored() const;
100 void setMirrored(bool);
101
102 QRectF sourceRect() const;
103 QRectF contentRect() const;
104
105 EndOfStreamPolicy endOfStreamPolicy() const;
106 void setEndOfStreamPolicy(EndOfStreamPolicy policy);
107
108 Q_REVISION(6, 9) Q_INVOKABLE void clearOutput();
109
110Q_SIGNALS:
111 void sourceChanged();
112 void fillModeChanged(QQuickVideoOutput::FillMode);
113 void orientationChanged();
114 void mirroredChanged();
115 void sourceRectChanged();
116 void contentRectChanged();
117 void endOfStreamPolicyChanged(QQuickVideoOutput::EndOfStreamPolicy);
118
119protected:
120 QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
121 void itemChange(ItemChange change, const ItemChangeData &changeData) override;
122 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
123 void releaseResources() override;
124
125private:
126 QSize nativeSize() const;
127 void updateGeometry();
128 QRectF adjustedViewport() const;
129
130 void setFrame(const QVideoFrame &frame);
131
132 void initRhiForSink();
133 void updateHdr(QSGVideoNode *videoNode);
134 void disconnectWindowConnections();
135
136private Q_SLOTS:
137 void _q_newFrame(QSize);
138 void _q_updateGeometry();
139
140private:
141 QSize m_nativeSize;
142
143 bool m_geometryDirty = true;
144 QRectF m_lastRect; // Cache of last rect to avoid recalculating geometry
145 QRectF m_contentRect; // Destination pixel coordinates, unclipped
146 int m_orientation = 0;
147 bool m_mirrored = false;
148 QtVideo::Rotation m_frameDisplayingRotation = QtVideo::Rotation::None;
149 Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio;
150
151 QPointer<QQuickWindow> m_window;
152 QVideoSink *m_sink = nullptr;
153 QVideoFrameFormat m_videoFormat;
154
155 QVideoFrameTexturePoolWPtr m_texturePool;
156 QVideoFrame m_frame;
157 bool m_frameChanged = false;
158 QMutex m_frameMutex;
159 QRectF m_renderedRect; // Destination pixel coordinates, clipped
160 QRectF m_sourceTextureRect; // Source texture coordinates
161
162 EndOfStreamPolicy m_endOfStreamPolicy = ClearOutput;
163
164 struct DestructorGuard
165 {
166 QMutex m_mutex;
167 bool m_isAlive{ true };
168
169 template <typename Functor>
170 void runWhileAlive(Functor &&f)
171 {
172 QMutexLocker lock(&m_mutex);
173 if (m_isAlive)
174 f();
175 }
176 };
177
178 std::shared_ptr<DestructorGuard> m_destructorGuard = std::make_shared<DestructorGuard>();
179
180 template <typename Functor>
181 auto makeGuardedCall(Functor &&f)
182 {
183 return [f = std::forward<Functor>(f), guard = m_destructorGuard](auto... params) {
184 if (g_signalBackoff) {
185 Q_UNLIKELY_BRANCH;
186 std::this_thread::sleep_for(*g_signalBackoff);
187 }
188
189 guard->runWhileAlive([&] {
190 f(params...);
191 });
192 };
193 }
194
195 // for testing
196 static std::optional<std::chrono::nanoseconds> g_signalBackoff;
197
198public:
199 static void setSignalBackoff(std::optional<std::chrono::nanoseconds>);
200};
201
202QT_END_NAMESPACE
203
204#endif // QQUICKVIDEOOUTPUT_P_H
Render video or camera viewfinder.