[AudioEngine] Do not crash on destruction after sample loading error

m_sampleLoader must be destroyed AFTER releasing the buffers it holds.
Also properly release sample on error and be safer
while destroying the buffer.

Change-Id: I5e39c6c815b8760f72cc5fdc61fad020d3cd1cc1
Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
This commit is contained in:
Konstantin Ritt
2015-04-11 23:17:18 +04:00
parent 37d5b53fae
commit fe1046794d

View File

@@ -89,7 +89,12 @@ public:
{ {
if (m_sample) if (m_sample)
m_sample->release(); m_sample->release();
alDeleteBuffers(1, &m_alBuffer);
if (m_alBuffer != 0) {
alGetError(); // clear error
alDeleteBuffers(1, &m_alBuffer);
QAudioEnginePrivate::checkNoError("delete buffer");
}
} }
void bindToSource(ALuint alSource) void bindToSource(ALuint alSource)
@@ -160,25 +165,34 @@ public Q_SLOTS:
alGenBuffers(1, &m_alBuffer); alGenBuffers(1, &m_alBuffer);
if (!QAudioEnginePrivate::checkNoError("create buffer")) { if (!QAudioEnginePrivate::checkNoError("create buffer")) {
decoderError();
return; return;
} }
alBufferData(m_alBuffer, alFormat, m_sample->data().data(), alBufferData(m_alBuffer, alFormat, m_sample->data().data(),
m_sample->data().size(), m_sample->format().sampleRate()); m_sample->data().size(), m_sample->format().sampleRate());
if (!QAudioEnginePrivate::checkNoError("fill buffer")) { if (!QAudioEnginePrivate::checkNoError("fill buffer")) {
decoderError();
return; return;
} }
m_isReady = true;
emit ready();
m_sample->release(); m_sample->release();
m_sample = 0; m_sample = 0;
m_isReady = true;
emit ready();
} }
void decoderError() void decoderError()
{ {
qWarning() << "loading [" << m_url << "] failed"; qWarning() << "loading [" << m_url << "] failed";
disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError())); disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
disconnect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
m_sample->release();
m_sample = 0;
emit error(); emit error();
} }
@@ -245,7 +259,6 @@ QAudioEnginePrivate::~QAudioEnginePrivate()
#ifdef DEBUG_AUDIOENGINE #ifdef DEBUG_AUDIOENGINE
qDebug() << "QAudioEnginePrivate::dtor"; qDebug() << "QAudioEnginePrivate::dtor";
#endif #endif
delete m_sampleLoader;
QObjectList children = this->children(); QObjectList children = this->children();
foreach (QObject *child, children) { foreach (QObject *child, children) {
QSoundSourcePrivate* s = qobject_cast<QSoundSourcePrivate*>(child); QSoundSourcePrivate* s = qobject_cast<QSoundSourcePrivate*>(child);
@@ -259,6 +272,8 @@ QAudioEnginePrivate::~QAudioEnginePrivate()
} }
m_staticBufferPool.clear(); m_staticBufferPool.clear();
delete m_sampleLoader;
ALCcontext* context = alcGetCurrentContext(); ALCcontext* context = alcGetCurrentContext();
ALCdevice *device = alcGetContextsDevice(context); ALCdevice *device = alcGetContextsDevice(context);
alcDestroyContext(context); alcDestroyContext(context);