aaudio: suspend a stream when its queue is full

This will prevent log spam when AAUDIO_CALLBACK_RESULT_STOP
is returned from an audio callback.

Bug: 120845500
Test: test_return_stop.cpp
Change-Id: Icfe1541d6fa7b045285ac3dfbb75dfed5424d49b
gugelfrei
Phil Burk 6 years ago
parent d00c4607a5
commit 762365c3ee

@ -258,7 +258,7 @@ void *AudioStreamInternalCapture::callbackLoop() {
callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP");
ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
break;
}
}

@ -293,7 +293,7 @@ void *AudioStreamInternalPlay::callbackLoop() {
break;
}
} else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
ALOGV("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
break;
}
}

@ -82,8 +82,9 @@ void *AAudioServiceEndpointCapture::callbackLoop() {
std::lock_guard <std::mutex> lock(mLockStreams);
for (const auto& clientStream : mRegisteredStreams) {
if (clientStream->isRunning()) {
if (clientStream->isRunning() && !clientStream->isSuspended()) {
int64_t clientFramesWritten = 0;
sp<AAudioServiceStreamShared> streamShared =
static_cast<AAudioServiceStreamShared *>(clientStream.get());

@ -84,6 +84,10 @@ void *AAudioServiceEndpointPlay::callbackLoop() {
int64_t clientFramesRead = 0;
bool allowUnderflow = true;
if (clientStream->isSuspended()) {
continue; // dead stream
}
aaudio_stream_state_t state = clientStream->getState();
if (state == AAUDIO_STREAM_STATE_STOPPING) {
allowUnderflow = false; // just read what is already in the FIFO

@ -179,6 +179,7 @@ aaudio_result_t AAudioServiceStreamBase::start() {
}
setFlowing(false);
setSuspended(false);
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
@ -345,7 +346,9 @@ aaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessag
}
int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
if (count != 1) {
ALOGE("%s(): Queue full. Did client die? %s", __func__, getTypeText());
ALOGW("%s(): Queue full. Did client stop? Suspending stream. what = %u, %s",
__func__, command->what, getTypeText());
setSuspended(true);
return AAUDIO_ERROR_WOULD_BLOCK;
} else {
return AAUDIO_OK;

@ -203,6 +203,20 @@ public:
return mFlowing;
}
/**
* Set false when the stream should not longer be processed.
* This may be caused by a message queue overflow.
* Set true when stream is started.
* @param suspended
*/
void setSuspended(bool suspended) {
mSuspended = suspended;
}
bool isSuspended() const {
return mSuspended;
}
/**
* Atomically increment the number of active references to the stream by AAudioService.
*
@ -304,7 +318,12 @@ private:
// This is modified under a global lock in AAudioStreamTracker.
int32_t mCallingCount = 0;
// This indicates that a stream that is being referenced by a binder call needs to closed.
std::atomic<bool> mCloseNeeded{false};
// This indicate that a running stream should not be processed because of an error,
// for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
std::atomic<bool> mSuspended{false};
};
} /* namespace aaudio */

Loading…
Cancel
Save