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