首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenSL ES RegisterCallback导致崩溃

OpenSL ES RegisterCallback导致崩溃
EN

Stack Overflow用户
提问于 2012-09-11 12:14:33
回答 1查看 1.6K关注 0票数 1

我不得不在我的项目中使用OpenSL (尝试过Soundpool,但它一点也不好)。然而,在多次播放声音(大约连续播放35次)后,应用程序被关闭(我猜可能是因为溢出)。

我试着释放缓冲区/内存来解决这个问题(看在上帝的份上,我不知道如何使用这个OpenSL)。因此,我决定在文件播放完毕后尝试释放。OpenSL ES为我们提供了RegisterCallback函数,这可能会有所帮助。出现了新的问题,在我的例子中(使用URI文件),RegisterCallback再次导致我的应用程序崩溃。卡住了。

这是我的代码。请帮帮忙。它在//register callback for uri之后崩溃了。

代码语言:javascript
复制
static short fdBuffer[SAWTOOTH_FRAMES];

// create URI audio player
    jboolean Java_jp_mobigame_ayakashi_CardGameActivity_createUriAudioPlayer(JNIEnv* env, jclass clazz,
            jstring uri)
    {
        __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri \n");
        SLresult result;

        // convert Java string to UTF-8
        const jbyte *utf8 = (*env)->GetStringUTFChars(env, uri, NULL);
        assert(NULL != utf8);

        // configure audio source
        // (requires the INTERNET permission depending on the uri parameter)
        SLDataLocator_URI loc_uri = {SL_DATALOCATOR_URI, (SLchar *) utf8};
        SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
        SLDataSource audioSrc = {&loc_uri, &format_mime};

        // configure audio sink
        SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
        SLDataSink audioSnk = {&loc_outmix, NULL};

        // create audio player
        const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO /*SL_IID_BUFFERQUEUE*/, SL_IID_VOLUME};
        const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
        result = (*engineEngine)->CreateAudioPlayer(engineEngine, &uriPlayerObject, &audioSrc,
                &audioSnk, 3, ids, req);
        // note that an invalid URI is not detected here, but during prepare/prefetch on Android,
        // or possibly during Realize on other platforms
        assert(SL_RESULT_SUCCESS == result);

        // release the Java string and UTF-8
        (*env)->ReleaseStringUTFChars(env, uri, utf8);

        // realize the player
        result = (*uriPlayerObject)->Realize(uriPlayerObject, SL_BOOLEAN_FALSE);
        // this will always succeed on Android, but we check result for portability to other platforms
        if (SL_RESULT_SUCCESS != result) {
            (*uriPlayerObject)->Destroy(uriPlayerObject);
            uriPlayerObject = NULL;
            return JNI_FALSE;
        }

        // get the play interface
        result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_PLAY, &uriPlayerPlay);
        assert(SL_RESULT_SUCCESS == result);

        // get the seek interface
        result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_SEEK, &uriPlayerSeek);
        assert(SL_RESULT_SUCCESS == result);


        __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 1\n");
        //get the buffer queue interface
        result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &uriPlayerBufferQueue);
        assert(SL_RESULT_SUCCESS == result);
        __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 2\n");


        //register callback for uri
        result = (*uriPlayerBufferQueue)->RegisterCallback(uriPlayerBufferQueue, bqUriPlayerCallback, NULL);
        assert(SL_RESULT_SUCCESS == result);
        __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 4\n");

        //Enqueue
        __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 3\n");
        result = (*uriPlayerBufferQueue)->Enqueue(uriPlayerBufferQueue, fdBuffer, sizeof(fdBuffer));


        // get the mute/solo interface
        result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_MUTESOLO, &uriPlayerMuteSolo);
        assert(SL_RESULT_SUCCESS == result);

        // get the volume interface
        result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_VOLUME, &uriPlayerVolume);
        assert(SL_RESULT_SUCCESS == result);

        return JNI_TRUE;

    }
EN

回答 1

Stack Overflow用户

发布于 2013-03-19 01:54:05

看起来您正在尝试获取一个缓冲队列接口,即使您正在指定一个uri源。你似乎也在询问数据。如果您只是尝试播放来自uri的音频,则不需要执行此操作。如果您尝试输出到缓冲区而不是扬声器,则这可能是有效的。我无论如何都不是OpenSL专家,所以这样做可能是有原因的。但是,如果没有原因,请尝试在player对象上注册回调。

代码语言:javascript
复制
(*uriPlayerPlay)->RegisterCallback(uriPlayerPlay, bqUriPlayerCallback, NULL);

顺便说一句,您可能想要设置回调事件掩码。有几个选项,但我相信您正在寻找的是:

代码语言:javascript
复制
(*uriPlayerPlay)->SetCallbackEventsMask(uriPlayerPlay, SL_PLAYEVENT_HEADATEND)

请注意,这可能会有问题。参见https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/7YaqlKlDMO4

如果这不起作用,看看你的回调函数的定义可能会有帮助。我相信它应该看起来像这样:

代码语言:javascript
复制
static void bqUriPlayerCallback (SLPlayItf caller, void *pContext, SLuint32 playevent)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12362662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档