OpenSL更改URI而不重新创建SLPlayItf

时间:2014-07-17 17:07:11

标签: android android-ndk java-native-interface opensl

我正在尝试更改音频播放器的uri,而不会破坏已实现的SLPlayItf对象。

我在代码中有这样的东西:

static SLDataSource audioSrcOne;
static SLDataLocator_URI locUriOne;

void initialize_player_with_streamOne()
{
  ...

  locUriOne.locatorType         = SL_DATALOCATOR_URI;
  locUriOne.URI                 = (SLchar *) streamOne->utf8;

  SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
  audioSrcOne.pLocator          = (void *)&locUriOne;
  audioSrcOne.pFormat           = (void *)&format_mime;

  ...

  result = ( *engine->engineEngine )->CreateAudioPlayer( engine->engineEngine, &( streamOne->playerObject ), &audioSrcOne, &audioSnkOne, 3, idm, reqm );
  assert( SL_RESULT_SUCCESS == result );

  ...
}

我认为SLDataSourceSLDataLocator_URI是作为指针发送给OpenSL的。如果我只是改变了它,那么新的网址就会被设置。

LOGV("STREAM ONE RESET - Configuring audio source %s", streamOne->utf8 );
locUriOne.URI = (SLchar *) streamOne->utf8;
LOGV("STREAM ONE RESET - %s", locUriOne.URI );

即使我可以看到URI指向新的char数组,但音频播放器仍在播放旧的。

有没有人知道如何在不破坏它的情况下更换音频播放器的当前网址?

PS:在更改URL之前,我正在向缓冲区和播放器对象发送SL_PLAYER_STOPPED。还清除缓冲区。但这并没有解决问题。

PSS:你会问我为什么不摧毁旧的音频播放器并创建一个新的音频播放器。那么答案是,样板太大了,不能破坏和创造。加上破坏/创造需要花费太多时间来满足我的口味。我更喜欢重新使用当前创建的对象。而且,当我创建第二个音频播放器时,我无法破坏第一个音频播放器。本机Destroy()命令挂起线程,代码不再响应。

1 个答案:

答案 0 :(得分:0)

我一直在挖掘opensl的​​来源,在IEngine.c文件中,我找到了这段代码:

    // Check the source and sink parameters against generic constraints,
    // and make a local copy of all parameters in case other application threads
    // change memory concurrently.

    result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
            DATALOCATOR_MASK_URI | DATALOCATOR_MASK_ADDRESS |
            DATALOCATOR_MASK_BUFFERQUEUE
#ifdef ANDROID
            | DATALOCATOR_MASK_ANDROIDFD | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
            | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
#endif
            , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM);

    if (SL_RESULT_SUCCESS != result) {
        break;
    }


   ... ...


   // It would be unsafe to ever refer to the application pointers again
   pAudioSrc = NULL;
   pAudioSnk = NULL;

如代码所示,复制音频源,然后为了线程安全而将传入指针设置为null。因此,似乎无法动态更改SLPlayItf的音频源。