1 | // Copyright (C) 2016 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qvideosink.h" |
5 | |
6 | #include "qvideoframeformat.h" |
7 | #include "qvideoframe.h" |
8 | #include "qmediaplayer.h" |
9 | #include "qmediacapturesession.h" |
10 | |
11 | #include <qvariant.h> |
12 | #include <qpainter.h> |
13 | #include <qmatrix4x4.h> |
14 | #include <QDebug> |
15 | #include <private/qplatformmediaintegration_p.h> |
16 | #include <private/qplatformvideosink_p.h> |
17 | |
18 | QT_BEGIN_NAMESPACE |
19 | |
20 | class QVideoSinkPrivate { |
21 | public: |
22 | QVideoSinkPrivate(QVideoSink *q) |
23 | : q_ptr(q) |
24 | { |
25 | auto maybeVideoSink = QPlatformMediaIntegration::instance()->createVideoSink(q); |
26 | if (maybeVideoSink) { |
27 | videoSink = maybeVideoSink.value(); |
28 | } else { |
29 | qWarning() << "Failed to create QVideoSink"<< maybeVideoSink.error(); |
30 | } |
31 | } |
32 | ~QVideoSinkPrivate() |
33 | { |
34 | delete videoSink; |
35 | } |
36 | void unregisterSource() |
37 | { |
38 | if (!source) |
39 | return; |
40 | auto *old = source; |
41 | source = nullptr; |
42 | if (auto *player = qobject_cast<QMediaPlayer *>(object: old)) |
43 | player->setVideoSink(nullptr); |
44 | else if (auto *capture = qobject_cast<QMediaCaptureSession *>(object: old)) |
45 | capture->setVideoSink(nullptr); |
46 | } |
47 | |
48 | QVideoSink *q_ptr = nullptr; |
49 | QPlatformVideoSink *videoSink = nullptr; |
50 | QObject *source = nullptr; |
51 | QRhi *rhi = nullptr; |
52 | }; |
53 | |
54 | /*! |
55 | \class QVideoSink |
56 | |
57 | \brief The QVideoSink class represents a generic sink for video data. |
58 | \inmodule QtMultimedia |
59 | \ingroup multimedia |
60 | \ingroup multimedia_video |
61 | |
62 | The QVideoSink class can be used to retrieve video data on a frame by frame |
63 | basis from Qt Multimedia. |
64 | |
65 | QVideoSink will provide individual video frames to the application developer |
66 | through the videoFrameChanged() signal. |
67 | |
68 | The video frame can then be used to read out the data of those frames and handle them |
69 | further. When using QPainter, the QVideoFrame can be drawing using the paint() method |
70 | in QVideoSink. |
71 | |
72 | QVideoFrame objects can consume a significant amount of memory or system resources and |
73 | should thus not be held for longer than required by the application. |
74 | |
75 | \sa QMediaPlayer, QMediaCaptureSession |
76 | |
77 | */ |
78 | |
79 | /*! |
80 | Constructs a new QVideoSink object with \a parent. |
81 | */ |
82 | QVideoSink::QVideoSink(QObject *parent) |
83 | : QObject(parent), |
84 | d(new QVideoSinkPrivate(this)) |
85 | { |
86 | qRegisterMetaType<QVideoFrame>(); |
87 | } |
88 | |
89 | /*! |
90 | Destroys the object. |
91 | */ |
92 | QVideoSink::~QVideoSink() |
93 | { |
94 | disconnect(receiver: this); |
95 | d->unregisterSource(); |
96 | delete d; |
97 | } |
98 | |
99 | /*! |
100 | Returns the QRhi instance being used to create texture data in the video frames. |
101 | */ |
102 | QRhi *QVideoSink::rhi() const |
103 | { |
104 | return d->rhi; |
105 | } |
106 | |
107 | /*! |
108 | \internal |
109 | Sets the QRhi instance being used to create texture data in the video frames |
110 | to \a rhi. |
111 | */ |
112 | void QVideoSink::setRhi(QRhi *rhi) |
113 | { |
114 | if (d->rhi == rhi) |
115 | return; |
116 | d->rhi = rhi; |
117 | if (d->videoSink) |
118 | d->videoSink->setRhi(rhi); |
119 | } |
120 | |
121 | /*! |
122 | \internal |
123 | */ |
124 | QPlatformVideoSink *QVideoSink::platformVideoSink() const |
125 | { |
126 | return d->videoSink; |
127 | } |
128 | |
129 | /*! |
130 | Returns the current video frame. |
131 | */ |
132 | QVideoFrame QVideoSink::videoFrame() const |
133 | { |
134 | return d->videoSink ? d->videoSink->currentVideoFrame() : QVideoFrame{}; |
135 | } |
136 | |
137 | /*! |
138 | \fn void QVideoSink::videoFrameChanged(const QVideoFrame &frame) const |
139 | |
140 | Signals when the video \a frame changes. |
141 | */ |
142 | /*! |
143 | Sets the current video \a frame. |
144 | */ |
145 | void QVideoSink::setVideoFrame(const QVideoFrame &frame) |
146 | { |
147 | if (d->videoSink) |
148 | d->videoSink->setVideoFrame(frame); |
149 | } |
150 | |
151 | /*! |
152 | \property QVideoSink::subtitleText |
153 | |
154 | Returns the current subtitle text. |
155 | */ |
156 | QString QVideoSink::subtitleText() const |
157 | { |
158 | return d->videoSink ? d->videoSink->subtitleText() : QString{}; |
159 | } |
160 | |
161 | /*! |
162 | Sets the current \a subtitle text. |
163 | */ |
164 | void QVideoSink::setSubtitleText(const QString &subtitle) |
165 | { |
166 | if (d->videoSink) |
167 | d->videoSink->setSubtitleText(subtitle); |
168 | } |
169 | |
170 | /*! |
171 | \property QVideoSink::videoSize |
172 | |
173 | Returns the size of the video currently being played back. If no video is |
174 | being played, this method returns an invalid size. |
175 | */ |
176 | QSize QVideoSink::videoSize() const |
177 | { |
178 | return d->videoSink ? d->videoSink->nativeSize() : QSize{}; |
179 | } |
180 | |
181 | void QVideoSink::setSource(QObject *source) |
182 | { |
183 | if (d->source == source) |
184 | return; |
185 | if (source) |
186 | d->unregisterSource(); |
187 | d->source = source; |
188 | } |
189 | |
190 | QT_END_NAMESPACE |
191 | |
192 | #include "moc_qvideosink.cpp" |
193 | |
194 | |
195 |