/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include "qaudiodecoder.h" #include "mockaudiodecoderservice.h" #include "mockmediaserviceprovider.h" class tst_QAudioDecoder : public QObject { Q_OBJECT public: tst_QAudioDecoder(); private Q_SLOTS: void init(); void ctors(); void read(); void stop(); void format(); void source(); void readAll(); void nullControl(); void nullService(); private: MockAudioDecoderService *mockAudioDecoderService; MockMediaServiceProvider *mockProvider; }; tst_QAudioDecoder::tst_QAudioDecoder() { } void tst_QAudioDecoder::init() { mockAudioDecoderService = new MockAudioDecoderService(this); mockProvider = new MockMediaServiceProvider(mockAudioDecoderService); QMediaServiceProvider::setDefaultServiceProvider(mockProvider); } void tst_QAudioDecoder::ctors() { QAudioDecoder d; QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.sourceFilename(), QString("")); d.setSourceFilename(""); QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.sourceFilename(), QString("")); } void tst_QAudioDecoder::read() { QAudioDecoder d; QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QSignalSpy readySpy(&d, SIGNAL(bufferReady())); QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool))); QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error))); // Starting with empty source == error d.start(); QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QCOMPARE(readySpy.count(), 0); QCOMPARE(bufferChangedSpy.count(), 0); QCOMPARE(errorSpy.count(), 1); // Set the source to something d.setSourceFilename("Blah"); QCOMPARE(d.sourceFilename(), QString("Blah")); readySpy.clear(); errorSpy.clear(); bufferChangedSpy.clear(); d.start(); QCOMPARE(d.state(), QAudioDecoder::DecodingState); QCOMPARE(d.bufferAvailable(), false); // not yet // Try to read QAudioBuffer b = d.read(); QVERIFY(!b.isValid()); // Read again with no parameter b = d.read(); QVERIFY(!b.isValid()); // Wait a while QTRY_VERIFY(d.bufferAvailable()); QVERIFY(d.bufferAvailable()); b = d.read(); QVERIFY(b.format().isValid()); QVERIFY(b.isValid()); QVERIFY(b.format().channelCount() == 1); QVERIFY(b.sampleCount() == 4); QVERIFY(readySpy.count() >= 1); QVERIFY(errorSpy.count() == 0); if (d.bufferAvailable()) { QVERIFY(bufferChangedSpy.count() == 1); } else { QVERIFY(bufferChangedSpy.count() == 2); } } void tst_QAudioDecoder::stop() { QAudioDecoder d; QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QSignalSpy readySpy(&d, SIGNAL(bufferReady())); QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool))); QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error))); // Starting with empty source == error d.start(); QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QCOMPARE(readySpy.count(), 0); QCOMPARE(bufferChangedSpy.count(), 0); QCOMPARE(errorSpy.count(), 1); // Set the source to something d.setSourceFilename("Blah"); QCOMPARE(d.sourceFilename(), QString("Blah")); readySpy.clear(); errorSpy.clear(); bufferChangedSpy.clear(); d.start(); QCOMPARE(d.state(), QAudioDecoder::DecodingState); QCOMPARE(d.bufferAvailable(), false); // not yet // Try to read QAudioBuffer b = d.read(); QVERIFY(!b.isValid()); // Read again with no parameter b = d.read(); QVERIFY(!b.isValid()); // Wait a while QTRY_VERIFY(d.bufferAvailable()); QVERIFY(d.bufferAvailable()); // Now stop d.stop(); QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); } void tst_QAudioDecoder::format() { QAudioDecoder d; QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.bufferAvailable() == false); QSignalSpy readySpy(&d, SIGNAL(bufferReady())); QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool))); QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error))); // Set the source to something d.setSourceFilename("Blah"); QCOMPARE(d.sourceFilename(), QString("Blah")); readySpy.clear(); errorSpy.clear(); bufferChangedSpy.clear(); d.start(); QCOMPARE(d.state(), QAudioDecoder::DecodingState); QCOMPARE(d.bufferAvailable(), false); // not yet // Try to read QAudioBuffer b = d.read(); QVERIFY(!b.isValid()); // Read again with no parameter b = d.read(); QVERIFY(!b.isValid()); // Wait a while QTRY_VERIFY(d.bufferAvailable()); b = d.read(); QVERIFY(d.audioFormat() == b.format()); // Setting format while decoding is forbidden QAudioFormat f(d.audioFormat()); f.setChannelCount(2); d.setAudioFormat(f); QVERIFY(d.audioFormat() != f); QVERIFY(d.audioFormat() == b.format()); // Now stop, and set something specific d.stop(); d.setAudioFormat(f); QVERIFY(d.audioFormat() == f); // Decode again d.start(); QTRY_VERIFY(d.bufferAvailable()); b = d.read(); QVERIFY(d.audioFormat() == f); QVERIFY(b.format() == f); } void tst_QAudioDecoder::source() { QAudioDecoder d; QVERIFY(d.sourceFilename().isEmpty()); QVERIFY(d.sourceDevice() == 0); QFile f; d.setSourceDevice(&f); QVERIFY(d.sourceFilename().isEmpty()); QVERIFY(d.sourceDevice() == &f); d.setSourceFilename("Foo"); QVERIFY(d.sourceFilename() == QString("Foo")); QVERIFY(d.sourceDevice() == 0); d.setSourceDevice(0); QVERIFY(d.sourceFilename().isEmpty()); QVERIFY(d.sourceDevice() == 0); d.setSourceFilename("Foo"); QVERIFY(d.sourceFilename() == QString("Foo")); QVERIFY(d.sourceDevice() == 0); d.setSourceFilename(QString()); QVERIFY(d.sourceFilename() == QString()); QVERIFY(d.sourceDevice() == 0); } void tst_QAudioDecoder::readAll() { QAudioDecoder d; d.setSourceFilename("Foo"); QVERIFY(d.state() == QAudioDecoder::StoppedState); QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64))); QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64))); QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State))); QSignalSpy finishedSpy(&d, SIGNAL(finished())); QSignalSpy bufferAvailableSpy(&d, SIGNAL(bufferAvailableChanged(bool))); d.start(); int i = 0; forever { QVERIFY(d.state() == QAudioDecoder::DecodingState); QCOMPARE(stateSpy.count(), 1); QCOMPARE(durationSpy.count(), 1); QVERIFY(finishedSpy.isEmpty()); QTRY_VERIFY(bufferAvailableSpy.count() >= 1); if (d.bufferAvailable()) { QAudioBuffer b = d.read(); QVERIFY(b.isValid()); QCOMPARE(b.startTime() / 1000, d.position()); QVERIFY(!positionSpy.isEmpty()); QList arguments = positionSpy.takeLast(); QCOMPARE(arguments.at(0).toLongLong(), b.startTime() / 1000); i++; if (i == MOCK_DECODER_MAX_BUFFERS) { QCOMPARE(finishedSpy.count(), 1); QCOMPARE(stateSpy.count(), 2); QVERIFY(d.state() == QAudioDecoder::StoppedState); QList arguments = stateSpy.takeLast(); QVERIFY(arguments.at(0).toInt() == (int)QAudioDecoder::StoppedState); QVERIFY(!d.bufferAvailable()); QVERIFY(!bufferAvailableSpy.isEmpty()); arguments = bufferAvailableSpy.takeLast(); QVERIFY(arguments.at(0).toBool() == false); break; } } else QTest::qWait(30); } } void tst_QAudioDecoder::nullControl() { mockAudioDecoderService->setControlNull(); QAudioDecoder d; QVERIFY(d.error() == QAudioDecoder::ServiceMissingError); QVERIFY(!d.errorString().isEmpty()); QVERIFY(d.hasSupport("MIME") == QMultimedia::MaybeSupported); QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.sourceFilename().isEmpty()); d.setSourceFilename("test"); QVERIFY(d.sourceFilename().isEmpty()); QFile f; QVERIFY(d.sourceDevice() == 0); d.setSourceDevice(&f); QVERIFY(d.sourceDevice() == 0); QAudioFormat format; format.setChannelCount(2); QVERIFY(!d.audioFormat().isValid()); d.setAudioFormat(format); QVERIFY(!d.audioFormat().isValid()); QVERIFY(!d.read().isValid()); QVERIFY(!d.bufferAvailable()); QVERIFY(d.position() == -1); QVERIFY(d.duration() == -1); d.start(); QVERIFY(d.error() == QAudioDecoder::ServiceMissingError); QVERIFY(!d.errorString().isEmpty()); QVERIFY(d.state() == QAudioDecoder::StoppedState); d.stop(); } void tst_QAudioDecoder::nullService() { mockProvider->service = 0; QAudioDecoder d; QVERIFY(d.error() == QAudioDecoder::ServiceMissingError); QVERIFY(!d.errorString().isEmpty()); QVERIFY(d.hasSupport("MIME") == QMultimedia::MaybeSupported); QVERIFY(d.state() == QAudioDecoder::StoppedState); QVERIFY(d.sourceFilename().isEmpty()); d.setSourceFilename("test"); QVERIFY(d.sourceFilename().isEmpty()); QFile f; QVERIFY(d.sourceDevice() == 0); d.setSourceDevice(&f); QVERIFY(d.sourceDevice() == 0); QAudioFormat format; format.setChannelCount(2); QVERIFY(!d.audioFormat().isValid()); d.setAudioFormat(format); QVERIFY(!d.audioFormat().isValid()); QVERIFY(!d.read().isValid()); QVERIFY(!d.bufferAvailable()); QVERIFY(d.position() == -1); QVERIFY(d.duration() == -1); d.start(); QVERIFY(d.error() == QAudioDecoder::ServiceMissingError); QVERIFY(!d.errorString().isEmpty()); QVERIFY(d.state() == QAudioDecoder::StoppedState); d.stop(); } QTEST_MAIN(tst_QAudioDecoder) #include "tst_qaudiodecoder.moc"