diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp index f6583e542735d93bd60ff20fb53ae4c711a7114f..06f2261df2afeb1983feae4612ec4d51d3437267 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.cpp +++ b/src/plugins/opensles/qopenslesaudiooutput.cpp @@ -71,7 +71,8 @@ QOpenSLESAudioOutput::QOpenSLESAudioOutput(const QByteArray &device) m_elapsedTime(0), m_processedBytes(0), m_availableBuffers(BUFFER_COUNT), - m_eventMask(SL_PLAYEVENT_HEADATEND) + m_eventMask(SL_PLAYEVENT_HEADATEND), + m_startRequiresInit(true) { #ifndef ANDROID m_streamType = -1; @@ -99,13 +100,10 @@ QAudio::State QOpenSLESAudioOutput::state() const void QOpenSLESAudioOutput::start(QIODevice *device) { Q_ASSERT(device); - destroyPlayer(); - - m_pullMode = true; - if (!preparePlayer()) return; + m_pullMode = true; m_audioSource = device; setState(QAudio::ActiveState); setError(QAudio::NoError); @@ -126,29 +124,20 @@ void QOpenSLESAudioOutput::start(QIODevice *device) // Change the state to playing. // We need to do this after filling the buffers or processedBytes might get corrupted. - if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) { - setError(QAudio::FatalError); - destroyPlayer(); - } + startPlayer(); } QIODevice *QOpenSLESAudioOutput::start() { - destroyPlayer(); - - m_pullMode = false; - if (!preparePlayer()) return Q_NULLPTR; + m_pullMode = false; m_audioSource = new SLIODevicePrivate(this); m_audioSource->open(QIODevice::WriteOnly | QIODevice::Unbuffered); // Change the state to playing - if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) { - setError(QAudio::FatalError); - destroyPlayer(); - } + startPlayer(); setState(QAudio::IdleState); return m_audioSource; @@ -159,7 +148,7 @@ void QOpenSLESAudioOutput::stop() if (m_state == QAudio::StoppedState) return; - destroyPlayer(); + stopPlayer(); setError(QAudio::NoError); } @@ -181,6 +170,7 @@ void QOpenSLESAudioOutput::setBufferSize(int value) if (m_state != QAudio::StoppedState) return; + m_startRequiresInit = true; m_bufferSize = value; } @@ -254,6 +244,7 @@ void QOpenSLESAudioOutput::resume() void QOpenSLESAudioOutput::setFormat(const QAudioFormat &format) { + m_startRequiresInit = true; m_format = format; } @@ -325,6 +316,7 @@ void QOpenSLESAudioOutput::setCategory(const QString &category) return; } + m_startRequiresInit = true; m_streamType = streamType; m_category = category; #endif // ANDROID @@ -403,6 +395,11 @@ void QOpenSLESAudioOutput::bufferQueueCallback(SLBufferQueueItf bufferQueue, voi bool QOpenSLESAudioOutput::preparePlayer() { + if (m_startRequiresInit) + destroyPlayer(); + else + return true; + SLEngineItf engine = QOpenSLESEngine::instance()->slEngine(); if (!engine) { qWarning() << "No engine"; @@ -543,20 +540,15 @@ bool QOpenSLESAudioOutput::preparePlayer() m_clockStamp.restart(); setError(QAudio::NoError); + m_startRequiresInit = false; return true; } void QOpenSLESAudioOutput::destroyPlayer() { - setState(QAudio::StoppedState); - - // We need to change the state manually... - if (m_playItf) - (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED); - - if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf)) - qWarning() << "Unable to clear buffer"; + if (m_state != QAudio::StoppedState) + stopPlayer(); if (m_playerObject) { (*m_playerObject)->Destroy(m_playerObject); @@ -582,6 +574,27 @@ void QOpenSLESAudioOutput::destroyPlayer() m_playItf = Q_NULLPTR; m_volumeItf = Q_NULLPTR; m_bufferQueueItf = Q_NULLPTR; + m_startRequiresInit = true; +} + +void QOpenSLESAudioOutput::stopPlayer() +{ + setState(QAudio::StoppedState); + + // We need to change the state manually... + if (m_playItf) + (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED); + + if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf)) + qWarning() << "Unable to clear buffer"; +} + +void QOpenSLESAudioOutput::startPlayer() +{ + if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) { + setError(QAudio::FatalError); + destroyPlayer(); + } } qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len) diff --git a/src/plugins/opensles/qopenslesaudiooutput.h b/src/plugins/opensles/qopenslesaudiooutput.h index d466ea64bf42b33aa9a04a400cc5b4083748c10b..200b4a3cc1ab4ceb86f340160b91a0f426d0eb4f 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.h +++ b/src/plugins/opensles/qopenslesaudiooutput.h @@ -86,6 +86,8 @@ private: bool preparePlayer(); void destroyPlayer(); + void stopPlayer(); + void startPlayer(); qint64 writeData(const char *data, qint64 len); void setState(QAudio::State state); @@ -113,6 +115,7 @@ private: qint64 m_processedBytes; QAtomicInt m_availableBuffers; SLuint32 m_eventMask; + bool m_startRequiresInit; qint32 m_streamType; QTime m_clockStamp;