2015-07-01 47 views
2

您好我正在Android JNI音頻部分,下面的jni代碼我從Android調用12次根據我的邏輯。只要第一個剪輯播放我發送回撥事件到Android,我再次呼籲selectClip()播放音頻剪輯。我可以打2次,但在第三次致電申請投擲錯誤爲libOpenSLES Leaving BufferQueue : SL_RESULT_BUFFER_INSUFFICIENT。 我錯過了什麼嗎? 同樣的任何指針來解決這個問題?作爲libOpenSLES獲取錯誤離開BufferQueue :: Enqueue(SL_RESULT_BUFFER_INSUFFICIENT)

jboolean flag=JNI_TRUE; 
jint clipNote = 0; 
// select the desired clip and play count, and enqueue the first buffer if idle 
JNIEXPORT jboolean JNICALL Java_com_example_nativeaudio_NativeAudio_selectClip(JNIEnv * env, jobject obj, 
      jint count) 
{ 
    // sleep logic 
    while((clock() - t)/1000 < 2000) { 
     usleep(10000); // sleep for 10ms 
    } 

    if(clipNote < 12) { 
     if(flag == JNI_TRUE) { 
      __android_log_print(ANDROID_LOG_DEBUG , "CustomTag", " flag = true : ClipNote : %d",clipNote); 
    clipNote = clipNote + 1; 
    nextBuffer = (short *) audio1; 
    nextSize = sizeof(audio1); 

    nextCount = count/2000; 
    if (nextSize > 0) { 
     // here we only enqueue one buffer because it is a long clip, 
     // but for streaming playback we would typically enqueue at least 2 buffers to start 
     SLresult result; 
     result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); 
     if (SL_RESULT_SUCCESS != result) { 
       return JNI_FALSE; 
     } 
    } 
    // callback to android 
    jclass cls = (*env)->GetObjectClass(env, obj); 
    jmethodID mid = (*env)->GetMethodID(env, cls, "callBackStart", "(I)V"); 
    if (mid == 0) { 
      return; 
    } 
    flag=JNI_FALSE; 
    (*env)->CallVoidMethod(env, obj, mid, clipNote); 
} else { 
    // callback to android 
    __android_log_print(ANDROID_LOG_DEBUG , "CustomTag", " flag = false"); 
    jclass cls = (*env)->GetObjectClass(env, obj); 
    jmethodID mid = (*env)->GetMethodID(env, cls, "callBackRelease", "(I)V"); 
    if (mid == 0) { 
     return; 
    } 
    flag = JNI_TRUE; 
    (*env)->CallVoidMethod(env, obj, mid, count); 
} 
t = clock(); 
} else { 
    SLresult result; 
    // make sure the asset audio player was created 
    if (NULL != fdPlayerPlay) { 
     result = (*fdPlayerPlay)>SetPlayState(fdPlayerPlay,SL_PLAYSTATE_PAUSED); 
     assert(SL_RESULT_SUCCESS == result); 
     (void)result; 
} 
} 
return JNI_TRUE; 
} 

回答

2

SL_RESULT_BUFFER_INSUFFICIENT由於定時問題而發生錯誤。 第二個線程在第一個線程完成之前開始。 第三個線程在前兩個進程中開始。這不能被處理,所以它會拋出一個錯誤。 時機增加到足以完成第一個線程,問題就解決了。

0

集numbuffers

機會是你的numbuffersSLDataLocator_AndroidSimpleBufferQueue是不適當的低。

SLDataLocator_AndroidSimpleBufferQueue in_loc; 
in_loc.numBuffers = 5; // what number do you have here? 

從OpenSL ES規格:

如果已經達到創建使用CreateAudioPlayer或CreateMidiPlayer方法媒體對象時用作數據源中的SLDataLocator_BufferQueue結構中指定的緩衝區的最大數量,緩衝區不會添加到緩衝區隊列中,並返回SL_RESULT_BUFFER_INSUFFICIENT。此時,客戶端應該等待,直到它收到一個緩衝區完成的回調通知,此時它可以排隊緩衝區。

替代

如果更改numbuffers,甚至一個非常高的數字不工作,請確保您的狀態設置爲播放:

(*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING); // begin playback