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
qaudiodecoder.cpp
Go to the documentation of this file.
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
5
6#include <private/qaudiodecoder_p.h>
7#include <private/qmultimediautils_p.h>
8#include <private/qplatformaudiodecoder_p.h>
9#include <private/qplatformmediaintegration_p.h>
10
11#include <QtCore/qcoreevent.h>
12#include <QtCore/qdebug.h>
13#include <QtCore/qmetaobject.h>
14#include <QtCore/qpointer.h>
15#include <QtCore/qtimer.h>
16#include <QtCore/qurl.h>
17
19
20/*!
21 \class QAudioDecoder
22 \brief The QAudioDecoder class implements decoding audio.
23 \inmodule QtMultimedia
24 \ingroup multimedia
25 \ingroup multimedia_audio
26
27 \preliminary
28
29 The QAudioDecoder class is a high level class for decoding
30 audio media files. It is similar to the QMediaPlayer class except
31 that audio is provided back through this API rather than routed
32 directly to audio hardware.
33
34 \sa QAudioBuffer
35*/
36
37/*!
38 Construct an QAudioDecoder instance with \a parent.
39*/
40QAudioDecoder::QAudioDecoder(QObject *parent) : QObject{ *new QAudioDecoderPrivate, parent }
41{
42 Q_D(QAudioDecoder);
43
44 auto maybeDecoder = QPlatformMediaIntegration::instance()->createAudioDecoder(this);
45 if (maybeDecoder) {
46 d->decoder.reset(maybeDecoder.value());
47 } else {
48 qWarning() << "Failed to initialize QAudioDecoder" << maybeDecoder.error();
49 }
50}
51
52/*!
53 Destroys the audio decoder object.
54*/
55QAudioDecoder::~QAudioDecoder() = default;
56
57/*!
58 Returns true is audio decoding is supported on this platform.
59*/
60bool QAudioDecoder::isSupported() const
61{
62 Q_D(const QAudioDecoder);
63
64 return bool(d->decoder);
65}
66
67/*!
68 \property QAudioDecoder::isDecoding
69 \brief \c true if the decoder is currently running and decoding audio data.
70*/
71bool QAudioDecoder::isDecoding() const
72{
73 Q_D(const QAudioDecoder);
74
75 return d->decoder && d->decoder->isDecoding();
76}
77
78/*!
79
80 Returns the current error state of the QAudioDecoder.
81*/
82QAudioDecoder::Error QAudioDecoder::error() const
83{
84 Q_D(const QAudioDecoder);
85 return d->decoder ? d->decoder->error() : NotSupportedError;
86}
87
88/*!
89 \property QAudioDecoder::error
90
91 Returns a human readable description of the current error, or
92 an empty string is there is no error.
93*/
94QString QAudioDecoder::errorString() const
95{
96 Q_D(const QAudioDecoder);
97 if (!d->decoder)
98 return tr("QAudioDecoder not supported.");
99 return d->decoder->errorString();
100}
101
102/*!
103 Starts decoding the audio resource.
104
105 As data gets decoded, the \l bufferReady() signal will be emitted
106 when enough data has been decoded. Calling \l read() will then return
107 an audio buffer without blocking.
108
109 If you call read() before a buffer is ready, an invalid buffer will
110 be returned, again without blocking.
111
112 \sa read()
113*/
114void QAudioDecoder::start()
115{
116 Q_D(QAudioDecoder);
117
118 if (!d->decoder)
119 return;
120
121 // Reset error conditions
122 d->decoder->clearError();
123 d->decoder->start();
124}
125
126/*!
127 Stop decoding audio. Calling \l start() again will resume decoding from the beginning.
128*/
129void QAudioDecoder::stop()
130{
131 Q_D(QAudioDecoder);
132
133 if (d->decoder)
134 d->decoder->stop();
135}
136
137/*!
138 Returns the current file name to decode.
139 If \l setSourceDevice was called, this will
140 be empty.
141*/
142QUrl QAudioDecoder::source() const
143{
144 Q_D(const QAudioDecoder);
145 return d->unresolvedUrl;
146}
147
148/*!
149 Sets the current audio file name to \a fileName.
150
151 When this property is set any current decoding is stopped,
152 and any audio buffers are discarded.
153
154 You can only specify either a source filename or
155 a source QIODevice. Setting one will unset the other.
156*/
157void QAudioDecoder::setSource(const QUrl &fileName)
158{
159 Q_D(QAudioDecoder);
160
161 if (!d->decoder)
162 return;
163
164 d->decoder->clearError();
165 d->unresolvedUrl = fileName;
166 d->decoder->setSourceDevice(nullptr);
167 QUrl url = qMediaFromUserInput(fileName);
168 d->decoder->setSource(url);
169}
170
171/*!
172 Returns the current source QIODevice, if one was set.
173 If \l setSource() was called, this will be a nullptr.
174*/
175QIODevice *QAudioDecoder::sourceDevice() const
176{
177 Q_D(const QAudioDecoder);
178 return d->decoder ? d->decoder->sourceDevice() : nullptr;
179}
180
181/*!
182 Sets the current audio QIODevice to \a device.
183
184 When this property is set any current decoding is stopped,
185 and any audio buffers are discarded.
186
187 You can only specify either a source filename or
188 a source QIODevice. Setting one will unset the other.
189*/
190void QAudioDecoder::setSourceDevice(QIODevice *device)
191{
192 Q_D(QAudioDecoder);
193 if (d->decoder) {
194 d->unresolvedUrl = QUrl{};
195 d->decoder->setSourceDevice(device);
196 }
197}
198
199/*!
200 Returns the audio format the decoder is set to.
201
202 \note This may be different than the format of the decoded
203 samples, if the audio format was set to an invalid one.
204
205 \sa setAudioFormat(), formatChanged()
206*/
207QAudioFormat QAudioDecoder::audioFormat() const
208{
209 Q_D(const QAudioDecoder);
210 return d->decoder ? d->decoder->audioFormat() : QAudioFormat{};
211}
212
213/*!
214 Set the desired audio format for decoded samples to \a format.
215
216 This property can only be set while the decoder is stopped.
217 Setting this property at other times will be ignored.
218
219 If the decoder does not support this format, \l error() will
220 be set to \c FormatError.
221
222 If you do not specify a format, the format of the decoded
223 audio itself will be used. Otherwise, some format conversion
224 will be applied.
225
226 If you wish to reset the decoded format to that of the original
227 audio file, you can specify an invalid \a format.
228
229 \warning Setting a desired audio format is not yet supported
230 on the Android backend. It does work with the default FFMPEG
231 backend.
232*/
233void QAudioDecoder::setAudioFormat(const QAudioFormat &format)
234{
235 if (isDecoding())
236 return;
237
238 Q_D(QAudioDecoder);
239
240 if (d->decoder)
241 d->decoder->setAudioFormat(format);
242}
243
244/*!
245 Returns true if a buffer is available to be read,
246 and false otherwise. If there is no buffer available, calling
247 the \l read() function will return an invalid buffer.
248*/
249bool QAudioDecoder::bufferAvailable() const
250{
251 Q_D(const QAudioDecoder);
252 return d->decoder && d->decoder->bufferAvailable();
253}
254
255/*!
256 Returns position (in milliseconds) of the last buffer read from
257 the decoder or -1 if no buffers have been read.
258*/
259
260qint64 QAudioDecoder::position() const
261{
262 Q_D(const QAudioDecoder);
263 return d->decoder ? d->decoder->position() : -1;
264}
265
266/*!
267 Returns total duration (in milliseconds) of the audio stream or -1
268 if not available.
269*/
270
271qint64 QAudioDecoder::duration() const
272{
273 Q_D(const QAudioDecoder);
274 return d->decoder ? d->decoder->duration() : -1;
275}
276
277/*!
278 Read a buffer from the decoder, if one is available. Returns an invalid buffer
279 if there are no decoded buffers currently available, or on failure. In both cases
280 this function will not block.
281
282 You should either respond to the \l bufferReady() signal or check the
283 \l bufferAvailable() function before calling read() to make sure
284 you get useful data.
285*/
286
287QAudioBuffer QAudioDecoder::read() const
288{
289 Q_D(const QAudioDecoder);
290 return d->decoder ? d->decoder->read() : QAudioBuffer{};
291}
292
293// Enums
294/*!
295 \enum QAudioDecoder::Error
296
297 Defines a media player error condition.
298
299 \value NoError No error has occurred.
300 \value ResourceError A media resource couldn't be resolved.
301 \value FormatError The format of a media resource isn't supported.
302 \value AccessDeniedError There are not the appropriate permissions to play a media resource.
303 \value NotSupportedError QAudioDecoder is not supported on this platform
304*/
305
306// Signals
307/*!
308 \fn void QAudioDecoder::error(QAudioDecoder::Error error)
309
310 Signals that an \a error condition has occurred.
311
312 \sa errorString()
313*/
314
315/*!
316 \fn void QAudioDecoder::sourceChanged()
317
318 Signals that the current source of the decoder has changed.
319
320 \sa source(), sourceDevice()
321*/
322
323/*!
324 \fn void QAudioDecoder::formatChanged(const QAudioFormat &format)
325
326 Signals that the current audio format of the decoder has changed to \a format.
327
328 \sa audioFormat(), setAudioFormat()
329*/
330
331/*!
332 \fn void QAudioDecoder::bufferReady()
333
334 Signals that a new decoded audio buffer is available to be read.
335
336 \sa read(), bufferAvailable()
337*/
338
339/*!
340 \fn void QAudioDecoder::bufferAvailableChanged(bool available)
341
342 Signals the availability (if \a available is true) of a new buffer.
343
344 If \a available is false, there are no buffers available.
345
346 \sa bufferAvailable(), bufferReady()
347*/
348
349/*!
350 \fn void QAudioDecoder::finished()
351
352 Signals that the decoding has finished successfully.
353 If decoding fails, error signal is emitted instead.
354
355 \sa start(), stop(), error()
356*/
357
358/*!
359 \fn void QAudioDecoder::positionChanged(qint64 position)
360
361 Signals that the current \a position of the decoder has changed.
362
363 \sa durationChanged()
364*/
365
366/*!
367 \fn void QAudioDecoder::durationChanged(qint64 duration)
368
369 Signals that the estimated \a duration of the decoded data has changed.
370
371 \sa positionChanged()
372*/
373
374// Properties
375/*!
376 \property QAudioDecoder::source
377 \brief the active filename being decoded by the decoder object.
378*/
379
380/*!
381 \property QAudioDecoder::bufferAvailable
382 \brief whether there is a decoded audio buffer available
383*/
384
385QT_END_NAMESPACE
386
387#include "moc_qaudiodecoder.cpp"