【问题标题】:OpenSL ES Android: "Too many objects" SL_RESULT_MEMORY_FAILUREOpenSL ES Android:“对象太多”SL_RESULT_MEMORY_FAILURE
【发布时间】:2014-05-08 14:49:47
【问题描述】:

我在 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;
}

【问题讨论】:

    标签: android opensl


    【解决方案1】:
    1. if (playerState == SL_OBJECT_STATE_REALIZED)

      不需要。试着一直这样做。

    2. AbortAsyncOperation 不需要在 Destroy => 中调用。

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

    编辑: 我测试了,找到了解决方案。 您不能从玩家callback 呼叫Destroy()。应该创建“destroy”列表并在其他地方销毁它,例如在主线程中。

    【讨论】:

    • 这里有一些可能对其他人有帮助的东西:上面提到的 32 个对象限制的参考:developer.android.com/ndk/guides/audio/opensl/… 如果 OpenSLES 在他们的日志中更明确地指定他们在谈论什么,那就太好了。
    猜你喜欢
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    • 2011-10-09
    • 2011-07-28
    • 2013-05-24
    • 2012-10-16
    相关资源
    最近更新 更多