[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:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user