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