Skip to content

Commit

Permalink
opensles: prevent crash in releaseBuffer
Browse files Browse the repository at this point in the history
Move call to getPosition() outside the callback.
This was triggering a restoreTrack_l() inside
AudioFlinger folowing a headset insertion.
That in turn caused an assert in releaseBuffer() in
AudioTrack or AudioRecord.

Now it is called when needed by getFramesRead() or getFramesWritten().

Fixes ##535
  • Loading branch information
philburk committed May 20, 2020
1 parent 7cdf71f commit d2430bf
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/oboe/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#define OBOE_VERSION_MINOR 4

// Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description.
#define OBOE_VERSION_PATCH 0
#define OBOE_VERSION_PATCH 1

#define OBOE_STRINGIFY(x) #x
#define OBOE_TOSTRING(x) OBOE_STRINGIFY(x)
Expand Down
21 changes: 10 additions & 11 deletions src/opensles/AudioStreamOpenSLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,23 +302,21 @@ int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) {

void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) {
bool stopStream = false;
// Ask the callback to fill the output buffer with data.
// Ask the app callback to process the buffer.
DataCallbackResult result = fireDataCallback(mCallbackBuffer.get(), mFramesPerCallback);
if (result == DataCallbackResult::Continue) {
// Update Oboe service position based on OpenSL ES position.
updateServiceFrameCounter();
// Pass the buffer to OpenSLES.
SLresult enqueueResult = enqueueCallbackBuffer(bq);
if (enqueueResult != SL_RESULT_SUCCESS) {
LOGE("%s() returned %d", __func__, enqueueResult);
stopStream = true;
}
// Update Oboe client position with frames handled by the callback.
if (getDirection() == Direction::Input) {
mFramesRead += mFramesPerCallback;
} else {
mFramesWritten += mFramesPerCallback;
}
// Pass the data to OpenSLES.
SLresult enqueueResult = enqueueCallbackBuffer(bq);
if (enqueueResult != SL_RESULT_SUCCESS) {
LOGE("%s() returned %d", __func__, enqueueResult);
stopStream = true;
}
} else if (result == DataCallbackResult::Stop) {
LOGD("Oboe callback returned Stop");
stopStream = true;
Expand All @@ -331,7 +329,7 @@ void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq
}
}

// this callback handler is called every time a buffer needs processing
// 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);
}
Expand Down Expand Up @@ -359,7 +357,8 @@ int32_t AudioStreamOpenSLES::getFramesPerBurst() {
return mFramesPerBurst;
}

int64_t AudioStreamOpenSLES::getFramesProcessedByServer() const {
int64_t AudioStreamOpenSLES::getFramesProcessedByServer() {
updateServiceFrameCounter();
int64_t millis64 = mPositionMillis.get();
int64_t framesProcessed = millis64 * getSampleRate() / kMillisPerSecond;
return framesProcessed;
Expand Down
2 changes: 1 addition & 1 deletion src/opensles/AudioStreamOpenSLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class AudioStreamOpenSLES : public AudioStreamBuffered {
mState.store(state);
}

int64_t getFramesProcessedByServer() const;
int64_t getFramesProcessedByServer();

// OpenSLES stuff
SLObjectItf mObjectInterface = nullptr;
Expand Down

0 comments on commit d2430bf

Please sign in to comment.