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
qvideoframeinput.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 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
5
6#include <QtMultimedia/qaudiobuffer.h>
7#include <QtMultimedia/private/qmediaframeinput_p.h>
8#include <QtMultimedia/private/qmediainputencoderinterface_p.h>
9#include <QtMultimedia/private/qplatformvideoframeinput_p.h>
10
12
14{
15public:
16 QVideoFrameInputPrivate(QVideoFrameInput *q) : q(q) { }
17
18 bool sendVideoFrame(const QVideoFrame &frame)
19 {
20 return sendMediaFrame([&]() { emit m_platfromVideoFrameInput->newVideoFrame(frame); });
21 }
22
23 void initialize(QVideoFrameFormat format = {})
24 {
25 m_platfromVideoFrameInput = std::make_unique<QPlatformVideoFrameInput>(std::move(format));
26 addUpdateSignal(m_platfromVideoFrameInput.get(), &QPlatformVideoFrameInput::encoderUpdated);
27 }
28
30 {
31 m_platfromVideoFrameInput.reset();
32
33 if (captureSession())
34 captureSession()->setVideoFrameInput(nullptr);
35 }
36
37 QPlatformVideoFrameInput *platfromVideoFrameInput() const
38 {
39 return m_platfromVideoFrameInput.get();
40 }
41
42protected:
45 {
46 if (prevSession)
47 removeUpdateSignal(prevSession, &QMediaCaptureSession::videoOutputChanged);
48
49 if (newSession)
50 addUpdateSignal(newSession, &QMediaCaptureSession::videoOutputChanged);
51 }
52
54 {
55 if (auto encoderInterface = m_platfromVideoFrameInput->encoderInterface())
56 return encoderInterface->canPushFrame();
57
58 return captureSession()->videoOutput() || captureSession()->videoSink();
59 }
60
61 void emitReadyToSendMediaFrame() override { emit q->readyToSendVideoFrame(); }
62
63private:
64 QVideoFrameInput *q = nullptr;
65 std::unique_ptr<QPlatformVideoFrameInput> m_platfromVideoFrameInput;
66};
67
68/*!
69 \class QVideoFrameInput
70 \inmodule QtMultimedia
71 \ingroup multimedia
72 \ingroup multimedia_video
73 \since 6.8
74
75 \brief The QVideoFrameInput class is used for providing custom video frames
76 to \l QMediaRecorder or a video output through \l QMediaCaptureSession.
77
78 QVideoFrameInput is only supported with the FFmpeg backend.
79
80 \include qmediainput-pull-mode.qdocinc {pull-mode} {QVideoFrameInput} {video frame} {sendVideoFrame} {readyToSendVideoFrame}
81
82 \snippet custommediainputsnippets/custommediainputsnippets.cpp QVideoFrameInput setup
83
84 Here's a minimal implementation of the slot function that provides video frames:
85
86 \snippet custommediainputsnippets/custommediainputsnippets.cpp nextVideoFrame()
87
88 For more details see readyToSendVideoFrame() and sendVideoFrame().
89
90 \sa QMediaRecorder, QMediaCaptureSession and QVideoSink.
91*/
92
93/*!
94 Constructs a new QVideoFrameInput object with \a parent.
95*/
96QVideoFrameInput::QVideoFrameInput(QObject *parent) : QVideoFrameInput({}, parent) { }
97
98/*!
99 Constructs a new QVideoFrameInput object with video frame \a format and \a parent.
100
101 The specified \a format will work as a hint for the initialization of the matching
102 video encoder upon invoking \l QMediaRecorder::record().
103 If the format is not specified or not valid, the video encoder will be initialized
104 upon sending the first frame.
105 Sending of video frames with another pixel format and size after initialization
106 of the matching video encoder might cause a performance penalty during recording.
107
108 We recommend specifying the format if you know in advance what kind of frames you're
109 going to send.
110*/
111QVideoFrameInput::QVideoFrameInput(const QVideoFrameFormat &format, QObject *parent)
112 : QObject(*new QVideoFrameInputPrivate(this), parent)
113{
114 Q_D(QVideoFrameInput);
115 d->initialize(format);
116}
117
118/*!
119 Destroys the object.
120 */
121QVideoFrameInput::~QVideoFrameInput()
122{
123 Q_D(QVideoFrameInput);
124 d->uninitialize();
125}
126
127/*!
128 Sends \l QVideoFrame to \l QMediaRecorder or a video output
129 through \l QMediaCaptureSession.
130
131 Returns \c true if the specified \a frame has been sent successfully
132 to the destination. Returns \c false, if the frame hasn't been sent,
133 which can happen if the instance is not assigned to
134 \l QMediaCaptureSession, the session doesn't have video outputs or
135 a media recorder, the media recorder is not started or its queue is full.
136 The signal \l readyToSendVideoFrame will be sent as soon as
137 the destination is able to handle a new frame.
138
139 Sending of an empty video frame is treated by \l QMediaRecorder
140 as an end of the input stream. QMediaRecorder stops the recording
141 automatically if \l QMediaRecorder::autoStop is \c true and
142 all the inputs have reported the end of the stream.
143*/
144bool QVideoFrameInput::sendVideoFrame(const QVideoFrame &frame)
145{
146 Q_D(QVideoFrameInput);
147 return d->sendVideoFrame(frame);
148}
149
150/*!
151 Returns the video frame format that was specified
152 upon construction of the video frame input.
153*/
154QVideoFrameFormat QVideoFrameInput::format() const
155{
156 Q_D(const QVideoFrameInput);
157 return d->platfromVideoFrameInput()->frameFormat();
158}
159
160/*!
161 Returns the capture session this video frame input is connected to, or
162 a \c nullptr if the video frame input is not connected to a capture session.
163
164 Use QMediaCaptureSession::setVideoFrameInput() to connect
165 the video frame input to a session.
166*/
167QMediaCaptureSession *QVideoFrameInput::captureSession() const
168{
169 Q_D(const QVideoFrameInput);
170 return d->captureSession();
171}
172
173void QVideoFrameInput::setCaptureSession(QMediaCaptureSession *captureSession)
174{
175 Q_D(QVideoFrameInput);
176 d->setCaptureSession(captureSession);
177}
178
179QPlatformVideoFrameInput *QVideoFrameInput::platformVideoFrameInput() const
180{
181 Q_D(const QVideoFrameInput);
182 return d->platfromVideoFrameInput();
183}
184
185/*!
186 \fn void QVideoFrameInput::readyToSendVideoFrame()
187
188 Signals that a new frame can be sent to the video frame input.
189 After receiving the signal, if you have frames to be sent, invoke \l sendVideoFrame
190 once or in a loop until it returns \c false.
191
192 \sa sendVideoFrame()
193*/
194
195QT_END_NAMESPACE
QPlatformVideoFrameInput * platfromVideoFrameInput() const
bool sendVideoFrame(const QVideoFrame &frame)
void initialize(QVideoFrameFormat format={})
QVideoFrameInputPrivate(QVideoFrameInput *q)
void updateCaptureSessionConnections(QMediaCaptureSession *prevSession, QMediaCaptureSession *newSession) override
void emitReadyToSendMediaFrame() override
bool checkIfCanSendMediaFrame() const override
Combined button and popup list for selecting options.