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); callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) { if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP"); ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
break; break;
} }
} }

@ -293,7 +293,7 @@ void *AudioStreamInternalPlay::callbackLoop() {
break; break;
} }
} else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) { } 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; break;
} }
} }

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

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

@ -179,6 +179,7 @@ aaudio_result_t AAudioServiceStreamBase::start() {
} }
setFlowing(false); setFlowing(false);
setSuspended(false);
// Start with fresh presentation timestamps. // Start with fresh presentation timestamps.
mAtomicTimestamp.clear(); mAtomicTimestamp.clear();
@ -345,7 +346,9 @@ aaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessag
} }
int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1); int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
if (count != 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; return AAUDIO_ERROR_WOULD_BLOCK;
} else { } else {
return AAUDIO_OK; return AAUDIO_OK;

@ -203,6 +203,20 @@ public:
return mFlowing; 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. * 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. // This is modified under a global lock in AAudioStreamTracker.
int32_t mCallingCount = 0; 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}; 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 */ } /* namespace aaudio */

Loading…
Cancel
Save