OpenSL меняет URI без повторного создания SLPlayItf

В настоящее время я пытаюсь изменить 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 );

  ...
}

Я думал, что SLDataSource и SLDataLocator_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 указывает на новый массив символов, аудиоплеер по-прежнему воспроизводит старый.

Кто-нибудь знает, как заменить текущий URL-адрес аудиоплеера, не уничтожая его?

PS: перед изменением URL-адреса я отправляю SL_PLAYER_STOPPED как в буфер, так и в объекты проигрывателя. Также очистка буферов. Но это не решило проблему.

PSS: Вы спросите меня, почему бы не уничтожить старый аудиоплеер и не создать новый. Что ж, ответ на этот вопрос таков: шаблон слишком велик, чтобы и разрушать, и создавать. К тому же, на мой вкус, уничтожение/создание занимает слишком много времени. Я предпочитаю повторно использовать текущие созданные объекты. А еще, когда я создаю второй аудиоплеер, я не могу уничтожить первый. Собственная команда Destroy() зависает в потоке, и код больше не отвечает.


person emrahgunduz    schedule 17.07.2014    source источник


Ответы (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 на лету невозможна.

person emrahgunduz    schedule 29.07.2014