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 "qgraphicsvideoitem.h"
5#include "qvideosink.h"
6
7#include <qobject.h>
8#include <qvideoframe.h>
9#include <qvideoframeformat.h>
10
11#include <QtCore/qcoreevent.h>
12#include <QtCore/qpointer.h>
13
14QT_BEGIN_NAMESPACE
15
16class QGraphicsVideoItemPrivate
17{
18public:
19 QGraphicsVideoItemPrivate()
20 : rect(0.0, 0.0, 320, 240)
21 {
22 }
23
24 QGraphicsVideoItem *q_ptr = nullptr;
25
26 QVideoSink *sink = nullptr;
27 QRectF rect;
28 QRectF boundingRect;
29 QSizeF nativeSize;
30 QVideoFrame m_frame;
31 Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio;
32
33 void updateRects();
34
35 void _q_present(const QVideoFrame &);
36};
37
38void QGraphicsVideoItemPrivate::updateRects()
39{
40 q_ptr->prepareGeometryChange();
41
42 boundingRect = rect;
43 if (nativeSize.isEmpty())
44 return;
45
46 if (m_aspectRatioMode == Qt::KeepAspectRatio) {
47 QSizeF size = nativeSize;
48 size.scale(s: rect.size(), mode: Qt::KeepAspectRatio);
49
50 boundingRect = QRectF(0, 0, size.width(), size.height());
51 boundingRect.moveCenter(p: rect.center());
52 }
53}
54
55void QGraphicsVideoItemPrivate::_q_present(const QVideoFrame &frame)
56{
57 m_frame = frame;
58 q_ptr->update(rect: boundingRect);
59
60 if (frame.isValid()) {
61 const QSize &size = frame.surfaceFormat().viewport().size();
62 if (nativeSize != size) {
63 nativeSize = size;
64
65 updateRects();
66 emit q_ptr->nativeSizeChanged(size: nativeSize);
67 }
68 }
69}
70
71/*!
72 \class QGraphicsVideoItem
73
74 \brief The QGraphicsVideoItem class provides a graphics item which display video produced by a QMediaPlayer or QCamera.
75
76 \inmodule QtMultimediaWidgets
77 \ingroup multimedia
78
79 Attaching a QGraphicsVideoItem to a QMediaPlayer or QCamera allows it to display
80 the video or image output of that media object.
81
82 \snippet multimedia-snippets/video.cpp Video graphics item
83
84 \b {Note}: Only a single display output can be attached to a media
85 object at one time.
86
87 \sa QMediaPlayer, QVideoWidget, QCamera
88*/
89
90/*!
91 Constructs a graphics item that displays video.
92
93 The \a parent is passed to QGraphicsItem.
94*/
95QGraphicsVideoItem::QGraphicsVideoItem(QGraphicsItem *parent)
96 : QGraphicsObject(parent)
97 , d_ptr(new QGraphicsVideoItemPrivate)
98{
99 d_ptr->q_ptr = this;
100 d_ptr->sink = new QVideoSink(this);
101
102 connect(sender: d_ptr->sink, SIGNAL(videoFrameChanged(const QVideoFrame &)), receiver: this, SLOT(_q_present(const QVideoFrame &)));
103}
104
105/*!
106 Destroys a video graphics item.
107*/
108QGraphicsVideoItem::~QGraphicsVideoItem()
109{
110 delete d_ptr;
111}
112
113/*!
114 \since 6.0
115 \property QGraphicsVideoItem::videoSink
116 \brief Returns the underlying video sink that can render video frames
117 to the current item.
118 This property is never \c nullptr.
119 Example of how to render video frames to QGraphicsVideoItem:
120 \snippet multimedia-snippets/video.cpp GraphicsVideoItem Surface
121 \sa QMediaPlayer::setVideoOutput
122*/
123
124QVideoSink *QGraphicsVideoItem::videoSink() const
125{
126 return d_func()->sink;
127}
128
129/*!
130 \property QGraphicsVideoItem::aspectRatioMode
131 \brief how a video is scaled to fit the graphics item's size.
132*/
133
134Qt::AspectRatioMode QGraphicsVideoItem::aspectRatioMode() const
135{
136 return d_func()->m_aspectRatioMode;
137}
138
139void QGraphicsVideoItem::setAspectRatioMode(Qt::AspectRatioMode mode)
140{
141 Q_D(QGraphicsVideoItem);
142 if (d->m_aspectRatioMode == mode)
143 return;
144
145 d->m_aspectRatioMode = mode;
146 d->updateRects();
147}
148
149/*!
150 \property QGraphicsVideoItem::offset
151 \brief the video item's offset.
152
153 QGraphicsVideoItem will draw video using the offset for its top left
154 corner.
155*/
156
157QPointF QGraphicsVideoItem::offset() const
158{
159 return d_func()->rect.topLeft();
160}
161
162void QGraphicsVideoItem::setOffset(const QPointF &offset)
163{
164 Q_D(QGraphicsVideoItem);
165
166 d->rect.moveTo(p: offset);
167 d->updateRects();
168}
169
170/*!
171 \property QGraphicsVideoItem::size
172 \brief the video item's size.
173
174 QGraphicsVideoItem will draw video scaled to fit size according to its
175 fillMode.
176*/
177
178QSizeF QGraphicsVideoItem::size() const
179{
180 return d_func()->rect.size();
181}
182
183void QGraphicsVideoItem::setSize(const QSizeF &size)
184{
185 Q_D(QGraphicsVideoItem);
186
187 d->rect.setSize(size.isValid() ? size : QSizeF(0, 0));
188 d->updateRects();
189}
190
191/*!
192 \property QGraphicsVideoItem::nativeSize
193 \brief the native size of the video.
194*/
195
196QSizeF QGraphicsVideoItem::nativeSize() const
197{
198 return d_func()->nativeSize;
199}
200
201/*!
202 \reimp
203*/
204QRectF QGraphicsVideoItem::boundingRect() const
205{
206 return d_func()->boundingRect;
207}
208
209/*!
210 \reimp
211*/
212void QGraphicsVideoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
213{
214 Q_D(QGraphicsVideoItem);
215
216 Q_UNUSED(option);
217 Q_UNUSED(widget);
218
219 d->m_frame.paint(painter, rect: d->rect, options: { .backgroundColor: Qt::transparent, .aspectRatioMode: d->m_aspectRatioMode });
220}
221
222/*!
223 \fn int QGraphicsVideoItem::type() const
224 \reimp
225
226 Returns an int representing the type of the video item.
227*/
228/*!
229 \variable QGraphicsVideoItem::d_ptr
230 \internal
231*/
232/*!
233 \enum QGraphicsVideoItem::anonymous
234 \internal
235
236 \omitvalue Type
237*/
238/*!
239 \reimp
240
241 \internal
242*/
243QVariant QGraphicsVideoItem::itemChange(GraphicsItemChange change, const QVariant &value)
244{
245 return QGraphicsItem::itemChange(change, value);
246}
247
248/*!
249 \internal
250*/
251void QGraphicsVideoItem::timerEvent(QTimerEvent *event)
252{
253 QGraphicsObject::timerEvent(event);
254}
255
256QT_END_NAMESPACE
257
258#include "moc_qgraphicsvideoitem.cpp"
259
260
261

source code of qtmultimedia/src/multimediawidgets/qgraphicsvideoitem.cpp