Changes to GStreamer backend for audio decoder.

Removed WaitingState.
New signals: finished(), positionChanged(), durationChanged().
New methods: position(), duration().
A parameter removed from read() method.
Unit tests updated.

Change-Id: Ie9d8a2804285c5542e592cce69963adbdf6ebfb8
Reviewed-by: Jonas Rabbe <jonas.rabbe@nokia.com>
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
Lev Zelenskiy
2012-02-24 12:50:32 +10:00
committed by Qt by Nokia
parent 0b8c6115cd
commit b56d3e70df
7 changed files with 270 additions and 70 deletions

View File

@@ -61,6 +61,7 @@ private Q_SLOTS:
void stop();
void format();
void source();
void readAll();
private:
MockAudioDecoderService *mockAudioDecoderService;
@@ -125,10 +126,7 @@ void tst_QAudioDecoder::read()
QCOMPARE(d.bufferAvailable(), false); // not yet
// Try to read
bool ok = false;
QAudioBuffer b = d.read(&ok);
QVERIFY(ok == false);
QAudioBuffer b = d.read();
QVERIFY(!b.isValid());
// Read again with no parameter
@@ -140,7 +138,7 @@ void tst_QAudioDecoder::read()
QVERIFY(d.bufferAvailable());
b = d.read(&ok);
b = d.read();
QVERIFY(b.format().isValid());
QVERIFY(b.isValid());
QVERIFY(b.format().channelCount() == 1);
@@ -189,10 +187,7 @@ void tst_QAudioDecoder::stop()
QCOMPARE(d.bufferAvailable(), false); // not yet
// Try to read
bool ok = false;
QAudioBuffer b = d.read(&ok);
QVERIFY(ok == false);
QAudioBuffer b = d.read();
QVERIFY(!b.isValid());
// Read again with no parameter
@@ -234,10 +229,7 @@ void tst_QAudioDecoder::format()
QCOMPARE(d.bufferAvailable(), false); // not yet
// Try to read
bool ok = false;
QAudioBuffer b = d.read(&ok);
QVERIFY(ok == false);
QAudioBuffer b = d.read();
QVERIFY(!b.isValid());
// Read again with no parameter
@@ -247,7 +239,7 @@ void tst_QAudioDecoder::format()
// Wait a while
QTRY_COMPARE(d.bufferAvailable(), 1);
b = d.read(&ok);
b = d.read();
QVERIFY(d.audioFormat() == b.format());
// Setting format while decoding is forbidden
@@ -267,7 +259,7 @@ void tst_QAudioDecoder::format()
d.start();
QTRY_COMPARE(d.bufferAvailable(), 1);
b = d.read(&ok);
b = d.read();
QVERIFY(d.audioFormat() == f);
QVERIFY(b.format() == f);
}
@@ -301,6 +293,51 @@ void tst_QAudioDecoder::source()
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<QVariant> 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<QVariant> 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);
}
}
QTEST_MAIN(tst_QAudioDecoder)
#include "tst_qaudiodecoder.moc"

View File

@@ -51,6 +51,8 @@
#include <QTimer>
#include <QIODevice>
#define MOCK_DECODER_MAX_BUFFERS 10
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -66,6 +68,7 @@ public:
: QAudioDecoderControl(parent)
, mState(QAudioDecoder::StoppedState)
, mDevice(0)
, mPosition(-1)
, mSerial(0)
{
mFormat.setChannels(1);
@@ -126,6 +129,7 @@ public:
if (!mSource.isEmpty()) {
mState = QAudioDecoder::DecodingState;
emit stateChanged(mState);
emit durationChanged(duration());
QTimer::singleShot(50, this, SLOT(pretendDecode()));
} else {
@@ -139,28 +143,33 @@ public:
if (mState != QAudioDecoder::StoppedState) {
mState = QAudioDecoder::StoppedState;
mSerial = 0;
mPosition = 0;
mBuffers.clear();
emit stateChanged(mState);
emit bufferAvailableChanged(false);
}
}
QAudioBuffer read(bool *ok)
QAudioBuffer read()
{
QAudioBuffer a;
if (mBuffers.length() > 0) {
if (ok)
*ok = true;
QAudioBuffer a = mBuffers.takeFirst();
if (mBuffers.length() == 0)
a = mBuffers.takeFirst();
mPosition = a.startTime() / 1000;
emit positionChanged(mPosition);
if (mBuffers.isEmpty())
emit bufferAvailableChanged(false);
QTimer::singleShot(50, this, SLOT(pretendDecode()));
return a;
} else {
// Can't do anything here :(
if (ok)
*ok = false;
return QAudioBuffer();
if (mBuffers.isEmpty() && mSerial >= MOCK_DECODER_MAX_BUFFERS) {
mState = QAudioDecoder::StoppedState;
emit finished();
emit stateChanged(mState);
} else
QTimer::singleShot(50, this, SLOT(pretendDecode()));
}
return a;
}
bool bufferAvailable() const
@@ -168,22 +177,33 @@ public:
return mBuffers.length() > 0;
}
qint64 position() const
{
return mPosition;
}
qint64 duration() const
{
return (sizeof(mSerial) * MOCK_DECODER_MAX_BUFFERS * qint64(1000)) / (mFormat.sampleRate() * mFormat.channels());
}
private slots:
void pretendDecode()
{
// Check if we've reached end of stream
if (mSerial >= MOCK_DECODER_MAX_BUFFERS)
return;
// We just keep the length of mBuffers to 3 or less.
if (mBuffers.length() < 3) {
QByteArray b(sizeof(mSerial), 0);
memcpy(b.data(), &mSerial, sizeof(mSerial));
qint64 position = (sizeof(mSerial) * mSerial * qint64(1000000)) / (mFormat.sampleRate() * mFormat.channels());
mSerial++;
mBuffers.push_back(QAudioBuffer(b, mFormat));
mBuffers.push_back(QAudioBuffer(b, mFormat, position));
emit bufferReady();
if (mBuffers.count() == 1)
emit bufferAvailableChanged(true);
} else {
// Can't do anything here, wait for a read to restart the timer
mState = QAudioDecoder::WaitingState;
emit stateChanged(mState);
}
}
@@ -192,6 +212,7 @@ public:
QString mSource;
QIODevice *mDevice;
QAudioFormat mFormat;
qint64 mPosition;
int mSerial;
QList<QAudioBuffer> mBuffers;