3

我在 Android 上遇到了 OpenSL ES 的问题。我正在使用 OpenSL 播放音效。目前,我每次播放声音时都会创建一个新播放器。(我知道这不是非常有效,但暂时“足够好”。)

播放一段时间后,我开始收到这些错误:

E/libOpenSLES(25131): Too many objects
W/libOpenSLES(25131): Leaving Engine::CreateAudioPlayer (SL_RESULT_MEMORY_FAILURE)

我正在跟踪我的创建/销毁模式,并且在任何给定时间我都不会超过 4 个未完成的对象,远低于 32 的系统限制。当然,这是假设 Destroy 正常工作。

我现在唯一的猜测是我在清理播放器对象时做错了什么。一个可能的问题是 Destroy 经常在播放器回调的上下文中调用(基本上是在播放完播放器后销毁播放器),尽管我找不到任何参考表明这是一个问题。除了“销毁”播放器对象之外,我还应该采取其他清理步骤吗?接口是否也需要以某种方式清理?

- 添加 -

经过更多测试后,在创建第 30 个玩家之后,它始终如一地发生(还有一个引擎和一个混合,所以总共有 32 个对象)。所以我一定不能正确地破坏物体。这是代码-我很想知道出了什么问题:

SLuint32 playerState = 0;

SLresult result = (*pPlayerObject)->GetState(pPlayerObject, &playerState);

return_if_fail(result);

if (playerState == SL_OBJECT_STATE_REALIZED)
{
    (*pPlayerObject)->AbortAsyncOperation(pPlayerObject);
    (*pPlayerObject)->Destroy(pPlayerObject);
}
else
{
    __android_log_print(1, LOG_TAG, "Player object in unexpected state (%d)", playerState);
    return 1002;
}
4

1 回答 1

2
  1. if (playerState == SL_OBJECT_STATE_REALIZED)

    不需要。试着总是这样做。

  2. AbortAsyncOperationDestroy =>不需要调用。

  3. 所以尝试一下就(*pPlayerObject)->Destroy(pPlayerObject);足够了。

编辑: 我进行了测试,并找到了解决方案。你不能Destroy()从 player打电话callback。应该制作“ destroy”列表并在其他地方销毁它,例如在主线程中。

于 2014-08-05T03:37:28.783 回答