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
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 4a0e6da..58ef7b1 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -258,7 +258,7 @@
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;
}
}
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 2ae37a5..9af47b2 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -293,7 +293,7 @@
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;
}
}
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 98288e1..37d105b 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -82,8 +82,9 @@
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());
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index ac0d61d..1e1c552 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -84,6 +84,10 @@
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
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 354b36a..defbb7b 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -179,6 +179,7 @@
}
setFlowing(false);
+ setSuspended(false);
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
@@ -345,7 +346,9 @@
}
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;
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index a1815d0..7904b25 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -204,6 +204,20 @@
}
/**
+ * 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.
*
* This is called under a global lock in AAudioStreamTracker.
@@ -304,7 +318,12 @@
// 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 */