AudioEngine:Fixed program may freeze if `AudioEngine::stop(int audioID)` or `AudioEngine::stopAll()` is invoked frequently on Android.

This commit is contained in:
WenhaiLin 2015-05-08 18:29:45 +08:00
parent 65ec7f9545
commit 07f5ec755a
2 changed files with 37 additions and 13 deletions

View File

@ -43,6 +43,8 @@
using namespace cocos2d;
using namespace cocos2d::experimental;
#define DELAY_TIME_TO_REMOVE 0.5f
void PlayOverEvent(SLPlayItf caller, void* context, SLuint32 playEvent)
{
if (context && playEvent == SL_PLAYEVENT_HEADATEND)
@ -67,6 +69,7 @@ AudioPlayer::AudioPlayer()
, _playOver(false)
, _loop(false)
, _assetFd(0)
, _delayTimeToRemove(-1.f)
{
}
@ -276,18 +279,32 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
void AudioEngineImpl::update(float dt)
{
auto itend = _audioPlayers.end();
for (auto iter = _audioPlayers.begin(); iter != itend; ++iter)
{
if(iter->second._playOver)
{
if (iter->second._finishCallback)
iter->second._finishCallback(iter->second._audioID, *AudioEngine::_audioIDInfoMap[iter->second._audioID].filePath);
AudioPlayer* player = nullptr;
AudioEngine::remove(iter->second._audioID);
_audioPlayers.erase(iter);
break;
auto itend = _audioPlayers.end();
for (auto iter = _audioPlayers.begin(); iter != itend; )
{
player = &(iter->second);
if (player->_playOver)
{
if (player->_finishCallback)
player->_finishCallback(player->_audioID, *AudioEngine::_audioIDInfoMap[player->_audioID].filePath);
AudioEngine::remove(player->_audioID);
iter = _audioPlayers.erase(iter);
continue;
}
else if (player->_delayTimeToRemove > 0.f)
{
player->_delayTimeToRemove -= dt;
if (player->_delayTimeToRemove < 0.f)
{
iter = _audioPlayers.erase(iter);
continue;
}
}
++iter;
}
if(_audioPlayers.empty()){
@ -348,7 +365,9 @@ void AudioEngineImpl::stop(int audioID)
log("%s error:%u",__func__, result);
}
_audioPlayers.erase(audioID);
//If destroy openSL object immediately,it may cause dead lock.
player._delayTimeToRemove = DELAY_TIME_TO_REMOVE;
//_audioPlayers.erase(audioID);
}
void AudioEngineImpl::stopAll()
@ -356,9 +375,13 @@ void AudioEngineImpl::stopAll()
auto itEnd = _audioPlayers.end();
for (auto it = _audioPlayers.begin(); it != itEnd; ++it)
{
auto result = (*it->second._fdPlayerPlay)->SetPlayState(it->second._fdPlayerPlay, SL_PLAYSTATE_STOPPED);
(*it->second._fdPlayerPlay)->SetPlayState(it->second._fdPlayerPlay, SL_PLAYSTATE_STOPPED);
if (it->second._delayTimeToRemove < 0.f)
{
//If destroy openSL object immediately,it may cause dead lock.
it->second._delayTimeToRemove = DELAY_TIME_TO_REMOVE;
}
}
_audioPlayers.clear();
}
float AudioEngineImpl::getDuration(int audioID)

View File

@ -60,6 +60,7 @@ private:
float _duration;
int _audioID;
int _assetFd;
float _delayTimeToRemove;
std::function<void (int, const std::string &)> _finishCallback;