【问题标题】:OpenSL changing URI without re-creating SLPlayItfOpenSL 更改 URI 而不重新创建 SLPlayItf
【发布时间】:2014-09-08 16:19:29
【问题描述】:

我目前正在尝试更改音频播放器的 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 的。如果我只是更改它,就会设置新的 url。

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

尽管我可以看到 URI 指向新的字符数组,但音频播放器仍在播放旧的。

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

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

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

【问题讨论】:

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


    【解决方案1】:

    我一直在挖掘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;
    

    正如代码所说,为了线程安全,音频源被复制,然后传入指针设置为空。因此,似乎无法即时更改 SLPlayItf 的音频源。

    【讨论】:

      猜你喜欢
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 2017-10-24
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多