Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenSL ES: Call processBufferCallback before setting the playstate to playing #1570

Merged
merged 4 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/opensles/AudioOutputStreamOpenSLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,26 @@ Result AudioOutputStreamOpenSLES::requestStart() {
setDataCallbackEnabled(true);

setState(StreamState::Starting);

if (getBufferDepth(mSimpleBufferQueueInterface) == 0) {
// Enqueue the first buffer if needed to start the streaming.
// We may need to stop the current stream.
bool shouldStopStream = processBufferCallback(mSimpleBufferQueueInterface);
if (shouldStopStream) {
LOGD("Stopping the current stream.");
if (requestStop_l() != Result::OK) {
LOGW("Failed to flush the stream. Error %s", convertToText(flush()));
}
setState(initialState);
mLock.unlock();
return Result::ErrorClosed;
}
}

Result result = setPlayState_l(SL_PLAYSTATE_PLAYING);
robertwu1 marked this conversation as resolved.
Show resolved Hide resolved
if (result == Result::OK) {
setState(StreamState::Started);
mLock.unlock();
if (getBufferDepth(mSimpleBufferQueueInterface) == 0) {
// Enqueue the first buffer if needed to start the streaming.
// This might call requestStop() so try to avoid a recursive lock.
processBufferCallback(mSimpleBufferQueueInterface);
}
} else {
setState(initialState);
mLock.unlock();
Expand Down Expand Up @@ -377,8 +388,12 @@ Result AudioOutputStreamOpenSLES::requestFlush_l() {
}

Result AudioOutputStreamOpenSLES::requestStop() {
LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
std::lock_guard<std::mutex> lock(mLock);
return requestStop_l();
}

Result AudioOutputStreamOpenSLES::requestStop_l() {
LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);

StreamState initialState = getState();
switch (initialState) {
Expand Down
2 changes: 2 additions & 0 deletions src/opensles/AudioOutputStreamOpenSLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class AudioOutputStreamOpenSLES : public AudioStreamOpenSLES {

Result requestFlush_l();

Result requestStop_l();

/**
* Set OpenSL ES PLAYSTATE.
*
Expand Down
20 changes: 12 additions & 8 deletions src/opensles/AudioStreamOpenSLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) {
return (result == SL_RESULT_SUCCESS) ? queueState.count : -1;
}

void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) {
bool stopStream = false;
bool AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) {
bool shouldStopStream = false;
// Ask the app callback to process the buffer.
DataCallbackResult result =
fireDataCallback(mCallbackBuffer[mCallbackBufferIndex].get(), mFramesPerCallback);
Expand All @@ -323,7 +323,7 @@ void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq
SLresult enqueueResult = enqueueCallbackBuffer(bq);
if (enqueueResult != SL_RESULT_SUCCESS) {
LOGE("%s() returned %d", __func__, enqueueResult);
stopStream = true;
shouldStopStream = true;
}
// Update Oboe client position with frames handled by the callback.
if (getDirection() == Direction::Input) {
Expand All @@ -333,20 +333,24 @@ void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq
}
} else if (result == DataCallbackResult::Stop) {
LOGD("Oboe callback returned Stop");
stopStream = true;
shouldStopStream = true;
} else {
LOGW("Oboe callback returned unexpected value = %d", result);
stopStream = true;
shouldStopStream = true;
}
if (stopStream) {
requestStop();
if (shouldStopStream) {
mCallbackBufferIndex = 0;
}
return shouldStopStream;
}

// This callback handler is called every time a buffer has been processed by OpenSL ES.
static void bqCallbackGlue(SLAndroidSimpleBufferQueueItf bq, void *context) {
(reinterpret_cast<AudioStreamOpenSLES *>(context))->processBufferCallback(bq);
bool shouldStopStream = (reinterpret_cast<AudioStreamOpenSLES *>(context))
->processBufferCallback(bq);
if (shouldStopStream) {
(reinterpret_cast<AudioStreamOpenSLES *>(context))->requestStop();
}
}

SLresult AudioStreamOpenSLES::registerBufferQueueCallback() {
Expand Down
4 changes: 3 additions & 1 deletion src/opensles/AudioStreamOpenSLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ class AudioStreamOpenSLES : public AudioStreamBuffered {
* Called by by OpenSL ES framework.
*
* This is public, but don't call it directly.
*
* @return whether the current stream should be stopped.
*/
void processBufferCallback(SLAndroidSimpleBufferQueueItf bq);
bool processBufferCallback(SLAndroidSimpleBufferQueueItf bq);

Result waitForStateChange(StreamState currentState,
StreamState *nextState,
Expand Down